Для тех, кто исследует тенденции на рынке труда или собирает информацию для найма, скрапинг вакансий на Indeed является важным инструментом. В этом руководстве описывается, как использовать Playwright для веб-скрапинга и lxml для парсинга HTML, чтобы извлекать данные о вакансиях, такие как название должности, имя работодателя, местоположение, описание должности и ссылки на вакансии. Завершающим этапом является сохранение собранной информации в формате CSV.
Для успешного выполнения скрапинга потребуется установка следующих библиотек Python:
Playwright: необходим для автоматизации браузера. Установите, используя команду:
pip install playwright
lxml: используется для парсинга HTML. Установите, используя команду:
pip install lxml
pandas: облегчает сохранение данных в формате CSV. Установите, используя команду:
pip install pandas
Установка браузеров через Playwright:
После установки Playwright, запустите следующую команду для установки необходимых бинарных файлов браузера:
playwright install
Для начала настроим Playwright на запуск браузера Chromium, переход на целевую веб-страницу и извлечение ее содержимого. Важным элементом этой настройки является использование прокси.
Почему стоит использовать прокси?
Использование прокси имеет ряд преимуществ, включая:
import asyncio
from playwright.async_api import async_playwright
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy = {
'server': '',
'username': '<логин>',
'password': '<пароль>'
}
) # Запуск браузера с отображением интерфейса
page = await browser.new_page()
await page.goto(url)
# Извлечение содержимого страницы
content = await page.content()
await browser.close() # Закрытие браузера после завершения
return content
В данном примере async_playwright инициирует запуск браузера с пользовательским интерфейсом, осуществляет переход по указанному URL и извлекает HTML-содержимое страницы.
После получения HTML-содержимого страницы следует его детальный анализ для извлечения необходимых данных. В этом процессе ключевую роль играет библиотека lxml, которая предоставляет мощные инструменты для анализа HTML. Lxml поддерживает использование XPath, что позволяет точно и эффективно локализовать и извлекать элементы данных из сложных веб-страниц.
from lxml import html
def parse_job_listings(content):
# Парсинг HTML-содержимого
parser = html.fromstring(content)
# Извлечение каждой вакансии с использованием XPath
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
jobs_data = []
for element in job_posting[:-1]: # Исключение последнего элемента, если это реклама или не относится к целевой информации для скрапинга
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# Добавление извлеченных данных в список jobs_data
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
import pandas as pd
async def scrape_indeed_jobs(url):
# Шаг 1: Получение содержимого страницы с помощью Playwright
content = await get_page_content(url)
# Шаг 2: Анализ HTML и извлечение информации о вакансиях
jobs_data = parse_job_listings(content)
return jobs_data
# URL для скрапинга
url = 'https ссылка'
# Скрапинг и сохранение данных
async def main():
# Скрапинг данных о вакансиях с указанного URL
jobs = await scrape_indeed_jobs(url)
# Шаг 3: Сохранение данных в CSV с помощью pandas
df = pd.DataFrame(jobs)
df.to_csv('indeed_jobs.csv', index=False)
print("Data saved to indeed_jobs.csv")
# Запуск главной функции
asyncio.run(main())
Сайт Indeed использует пагинацию для разбиения списка вакансий на множество страниц. Это удобно, поскольку позволяет распределить информацию и снизить нагрузку на серверы, но требует дополнительной логики в скрапере для перехода по страницам. Каждая новая страница в списке вакансий доступна через изменение параметра start в URL, который увеличивается на 10 с каждой новой страницей.
Чтобы адаптировать скрапер к этому механизму, можно создать функцию scrape_multiple_pages, которая будет модифицировать базовый URL, увеличивая параметр start для доступа к каждой следующей странице. Этот подход позволяет систематически собирать данные со всех страниц, увеличивая охват и количество собираемых вакансий.
async def scrape_multiple_pages(base_url, pages=3):
all_jobs = []
for page_num in range(pages):
# Обновление URL для пагинации
url = f"{base_url}&start={page_num * 10}"
print(f"Scraping page: {url}")
# Скрапинг данных о вакансиях с каждой страницы
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# Сохранение всех вакансий в CSV
df = pd.DataFrame(all_jobs)
df.to_csv('indeed_jobs_all_pages.csv', index=False)
print("Data saved to indeed_jobs_all_pages.csv")
# Скрапинг нескольких страниц списка вакансий
asyncio.run(scrape_multiple_pages('https ссылка', pages=3))
Для того чтобы скрапить информацию по конкретным должностям или ключевым словам, необходимо настроить параметр поиска query в URL сайта Indeed. Это позволяет целенаправленно извлекать данные по интересующим профессиям или секторам. Например, для поиска вакансий Python-разработчика на сайте www.indeed.com.
query = "python+developer"
base_url = f"https://www.indeed.com/jobs?q={query}"
asyncio.run(scrape_multiple_pages(base_url, pages=3))
Изменяя значение параметра query на желаемые названия должностей или ключевые слова, можно адаптировать скрапер к различным задачам по сбору данных. Это дает гибкость в выборе целевых вакансий и позволяет эффективно собирать информацию с Indeed, адаптируясь к изменяющимся требованиям рынка труда.
import asyncio
from playwright.async_api import async_playwright
from lxml import html
import pandas as pd
# Шаг 1: Получение содержимого страницы с помощью Playwright
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False
proxy = {
'server': '',
'username': '<логин>',
'password': '<пароль>'
}
) # Запуск браузера с интерфейсом
page = await browser.new_page()
await page.goto(url, wait_until='networkidle')
# Извлечение содержимого страницы
content = await page.content()
await browser.close() # Закрытие браузера после использования
return content
# Шаг 2: Разбор HTML-содержимого с помощью lxml
def parse_job_listings(content):
# Разбор HTML с помощью lxml
parser = html.fromstring(content)
# Выбор отдельных объявлений о работе с помощью XPath
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
# Извлечение данных о работе
jobs_data = []
for element in job_posting[:-1]:
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# Добавление извлеченных данных в список jobs_data
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
# Шаг 3: Скрапинг вакансий Indeed для одной страницы
async def scrape_indeed_jobs(url):
# Получение содержимого страницы с помощью Playwright
content = await get_page_content(url)
# Разбор HTML и извлечение данных о работе
jobs_data = parse_job_listings(content)
return jobs_data
# Шаг 4: Управление пагинацией и скрапинг множества страниц
async def scrape_multiple_pages(base_url, query, pages=3):
all_jobs = []
for page_num in range(pages):
# Обновление URL для управления пагинацией и добавление поискового запроса
url = f"{base_url}?q={query}&start={page_num * 10}"
print(f"Scraping page: {url}")
# Скрапинг вакансий для текущей страницы
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# Сохранение всех вакансий в CSV-файл
df = pd.DataFrame(all_jobs)
df.to_csv(f'indeed_jobs_{query}.csv', index=False)
print(f"Data saved to indeed_jobs_{query}.csv")
# Функция для запуска скрапера с динамическим вводом запроса пользователя
async def run_scraper():
# Шаг 5: Запрос у пользователя ввода поискового запроса и количества страниц для скрапинга
query = input("Введите название должности или ключевые слова для поиска (например, python+developer): ")
pages = int(input("Введите количество страниц для скрапинга: "))
# Скрапинг вакансий на нескольких страницах в соответствии с запросом
base_url = 'https://www.indeed.com/jobs'
await scrape_multiple_pages(base_url, query, pages)
# Запуск скрапера
asyncio.run(run_scraper())
Чтобы обеспечить бесперебойный процесс скрапинга и уменьшить риск блокировок и появления капчи, необходимо выбрать правильный прокси-сервер. Наиболее оптимальным вариантом для скрапинга являются ISP прокси, которые обеспечивают высокую скорость и стабильность соединения, а также имеют высокий траст-фактор, благодаря чему редко блокируются платформами. Данный тип прокси является статическим, поэтому для масштабного скрапинга необходимо сформировать пул ISP прокси и настроить ротацию IP-адресов для их регулярной смены. Альтернативным вариантом станут резидентские прокси, которые являются динамическими и имеют наибольшее географическое покрытие в сравнении с другими типами прокси-серверов.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.ru!
Комментарии: 0