Всем привет! Сегодня я покажу, как можно собрать данные о вакансиях с популярной платформы поиска работы Indeed.com. Мы будем использовать Python и его библиотеки Requests и Beautiful Soup.

Во-первых, давайте возьмем веб-страницу, с которой мы хотели бы извлечь данные. Если вы будете искать объявления о вакансиях на сайте Indeed, вы увидите похожую страницу:

Чтобы просмотреть эту страницу, нажмите Ctrl+Shift+I, чтобы открыть веб-инструменты Chrome (если вы используете веб-браузер Chrome) и посмотрите на вкладку элементов:

Вы увидите, что к каждому объявлению о вакансии на странице прикреплена ссылка (тег ‹a›). Нам нужно получить URL из этого тега. Для этого давайте создадим функцию, которая будет извлекать URL-адреса вакансий. Но сначала давайте импортируем библиотеки, которые нам понадобятся:

from bs4 import BeautifulSoup
import pandas as pd
import requests
import os
import argparse
from tqdm import tqdm

Нет, давайте создадим функцию для извлечения URL:

headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'referer': 'https://play.google.com/store/apps',
'accept-language': 'en-US,en;q=0.9,',
'cookie': 'prov=6bb44cc9-dfe4-1b95-a65d-5250b3b4c9fb; _ga=GA1.2.1363624981.1550767314; __qca=P0-1074700243-1550767314392; notice-ctt=4%3B1550784035760; _gid=GA1.2.1415061800.1552935051; acct=t=4CnQ70qSwPMzOe6jigQlAR28TSW%2fMxzx&s=32zlYt1%2b3TBwWVaCHxH%2bl5aDhLjmq4Xr',
}
def get_job_urls(URL: str) -> list:
'''
Extracts job urls from the search result page given by URL
'''
res = requests.get(URL, headers=headers).content
soup = BeautifulSoup(res, "html.parser")
job_urls = [a['href'] for a in soup.find_all(
'a', {"id": lambda x: x and x.startswith('job_')})]
return job_urls

Во-первых, мы отправляем запрос GET на URL-адрес поиска Indeed, а затем анализируем полученный ответ с помощью Beautiful Soup. После этого мы будем искать все ссылки (тег «а») с классом, имя которого начинается с «job_» и из каждого тега получать атрибут «href» (сама ссылка). Затем мы возвращаем список всех URL-адресов вакансий, которые мы нашли на странице поиска.

После того, как мы получили несколько URL-адресов вакансий, нам нужно извлечь информацию с этих веб-страниц. Давайте посмотрим на структуру веб-страницы объявления о вакансии:

Каждая страница с вакансиями на сайте Indeed выглядит примерно так, как показано на изображении выше: на ней есть название должности, название компании, диапазон заработной платы и описание. Мы хотим извлечь всю эту информацию со страницы. Для этого давайте посмотрим на HTML страницы:

Мы видим, что название должности — это тег h1 с определенным классом. Итак, чтобы извлечь название должности, мы можем сделать что-то вроде этого:

title = soup.find('h1').text

Чтобы получить информацию о компании и местоположении, нам нужно извлечь этот тег div:

job_info = job_info_main.find(
'div', {"class": lambda x: x and x.startswith(
'jobsearch-CompanyInfoWithoutHeaderImage')}

Чтобы получить описание, нам нужно извлечь текст из тегов div (также тегов p), которые содержатся в этом div с идентификатором «jobDescriptionText»:

После этого возвращаем все данные, которые мы получили для объявления о вакансии:

def get_job_info(job_url: str) -> tuple:
'''
Extracts job info from the job URL
'''
job_url = 'https://www.indeed.com'+job_url
res = requests.get(job_url, headers=headers).content
soup = BeautifulSoup(res, "html.parser")
title = soup.find('h1').text
job_info_main = soup.find(
'div', {"class": lambda x: x and x.startswith('jobsearch')})
job_info = job_info_main.find(
'div', {"class": lambda x: x and x.startswith(
'jobsearch-CompanyInfoWithoutHeaderImage')}
)
company = job_info.find(
'div', {'class': lambda x: x and x.startswith('icl-u')}).text
job = job_info.find_all(
'div', {'class': None})
location = [i.text for i in job][-1]
try:
salary_emp, salary_est = [li.text for li in job_info_main.find(
'ul', {'class': lambda x: x and x.startswith('css-1lyr5hv')}).find_all('li')]
except AttributeError:
salary_emp, salary_est = '', ''
job_description = job_info_main.find('div', {'id': 'jobDescriptionText'})
description = [d.text.lstrip()
for d in job_description.find_all(['p', 'div'])]
description = ' '.join(description)
return (title, company, location, salary_emp,
salary_est, description)

Чтобы мы могли извлечь URL-адреса вакансий со страницы поиска и получить информацию о каждой работе. Чтобы увидеть полный пример (с интерфейсом CLI), ознакомьтесь с этим GitHub Repo.

Вот и все! Если вам это нравится или у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь оставлять комментарии и счастливого кодирования!