Соскреб в Интернете, когда порядок элементов перетасовывается с нумерацией страниц - действительно, рабочие места - PullRequest
0 голосов
/ 27 мая 2019

Я пытаюсь записать информацию с сайта вакансий действительно для всех вакансий, связанных с определенным поисковым запросом.Тем не менее, хотя при поиске этого термина он говорит о наличии X рабочих мест (т. Е. «Показывает страницу 1 из X рабочих мест»), количество уникальных рабочих мест (я удаляю запись I намного меньше. Число также не соответствует, если яПовторите скребок, и там будут дубликаты.
Это заставляет меня задуматься, не происходит ли перетасовка содержимого (например, выборка с заменой), чтобы были уникальные задания, которые я не вижу. В качестве альтернативы можно указать количество заданий.неправильно отображается на сайте. Например, , если вы переходите на последнюю страницу , это показывает только приблизительно 620 рабочих мест предполагаемого 920. Но это не объясняет, почему я не получаю последовательното же количество уникальных результатов, если я дважды выполню код дважды.

Есть мысли?

Код Python3 здесь, если вы хотите его запустить. Требуются: запросы, bs4, pandas,numpy

# modified from https://medium.com/@msalmon00/web-scraping-job-postings-from-indeed-96bd588dcb4b
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import json
from html.parser import HTMLParser
from datetime import datetime
import numpy as np
import re
from itertools import chain

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.strict = False
        self.convert_charrefs= True
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def get_data(self):
        return ''.join(self.fed)

def strip_tags(html):
    s = MLStripper()
    s.feed(html)
    result = s.get_data()
    # result = result.strip('\n')
    result = result.replace('\n',' ')
    return result

keyword = 'sustainability'
state = 'mi'
page_limit = 50

# init the dataframe
columns = ['job_code','keyword', 'job_title', 'company_name', 'location', 'salary']
jobs = []
div_list = []

# determine max number of results
page = requests.get('http://www.indeed.com/jobs?q={}&l={}'.format(keyword,state.lower()))
soup = BeautifulSoup(page.content, "html.parser")
max_result_bs4 = soup.find(name='div', attrs = {'id':'searchCount'})#.find('directory').text
max_results = int(max_result_bs4.contents[0].split(' ')[-2].replace(',',''))

#scraping code:
# loop through pages
for start in chain(range(0, max_results, page_limit),range(0, max_results, page_limit)):
    url = 'https://www.indeed.com/jobs?q={}&start={}&limit={}&l={}&sort=date'.format(keyword, start, page_limit, state.lower())
    page = requests.get(url)
    time.sleep(0.01)  #ensuring at least 0.01 second between page grabs
    soup = BeautifulSoup(page.content, 'html.parser', from_encoding='utf-8')
    # record the divs
    div_list += soup.find_all(name='div', attrs={'data-tn-component': 'organicJob'})
# format the scrapes
for div in div_list:
    #creating an empty list to hold the data for each posting
    job_post = []
    # get the job code
    job_code = div['data-jk']
    job_post.append(job_code)
    #append keyword name
    job_post.append(keyword)
    #grabbing job title
    for a in div.find_all(name='a', attrs={'data-tn-element':'jobTitle'}):
        title = a['title']
        if title:
            job_post.append(title)
        else:
            job_post.append('Not found')
    #grabbing company name
    company = div.find_all(name='span', attrs={'class':'company'})
    if len(company) > 0:
        for b in company:
            job_post.append(b.text.strip())
    else:
        sec_try = div.find_all(name='span', attrs={'class':'result-link-source'})
        for span in sec_try:
            job_post.append(span.text)
    if len(job_post) == 3:
        job_post.append('Not found')
    #grabbing location name
    job_post.append(state)
    #grabbing salary
    try:
        job_post.append(div.find('nobr').text)
    except:
        try:
            job_post.append(div.find(name='span', attrs={'class':'salary no-wrap'}).text.strip())
        except:
            job_post.append('Nothing_found')
    #appending list of job post info to dataframe at index num
    jobs.append(job_post)

df = pd.DataFrame(jobs, columns = columns)

#saving df as a local csv file — define your own local path to save contents
todays_date = datetime.now().strftime('%Y%m%d')
df.to_csv('indeed_{}.csv'.format(todays_date), encoding='utf-8')

df_len = len(df)
unique_jobs = len(np.unique(df.job_code))
print('Found {} unique jobs from an alleged {} after recording {} postings'.format(unique_jobs, max_results, df_len))
...