Indeed зарекомендовал себя как сайт вакансий № 1 среди конкурентов, таких как Monster и CareerBuilder, всего за 5 лет после своего запуска в 2004 году. Сегодня Indeed имеет более 250 миллионов уникальных посетителей в месяц, просматривающих его базу данных, содержащую сотни миллионов списков вакансий по всему миру.
Учитывая такой огромный объем данных, неудивительно, что рекрутеры, исследователи и другие опытные пользователи хотят извлекать и анализировать информацию о листингах в больших масштабах. Indeed предоставляет API, но у него есть строгие ежедневные ограничения, которые не позволяют собирать полные данные. Вот тут-то и пригодится тщательное и этичное парсинг веб-страниц!
В этом подробном руководстве, состоящем из более чем 2,500 слов, мы рассмотрим различные инструменты и методы парсинга списков вакансий Indeed с точки зрения опытного эксперта по парсингу веб-страниц.
Действительно ли парсинг веб-страниц законен и этичен?
Прежде чем мы перейдем к практическим рекомендациям, важно рассмотреть законность и этику парсинга веб-страниц списков вакансий Indeed.
Законность
Во многих юрисдикциях законность парсинга веб-страниц находится в серой зоне. Есть несколько ключевых факторов, которые следует учитывать:
Авторские права – Собирайте только фактические данные, а не существенный оригинальный контент, защищенный авторским правом. Воспроизведение больших частей описаний объявлений или профилей компаний может быть запрещено без разрешения.
Нарушения Условий использования – Сбор данных способом, нарушающим Условия обслуживания сайта (например, обратный инжиниринг, чрезмерные запросы), может быть проблематичным и может привести к судебному разбирательству (как в случае с Facebook против Power Ventures). Условия использования Indeed разрешают парсинг данных в личных и некоммерческих целях.
Нормативно-правовые акты – Помните о региональных правилах конфиденциальности, таких как GDPR и CCPA, которые ограничивают сбор личных пользовательских данных без согласия жителей ЕС и Калифорнии соответственно.
CFAA – Закон о компьютерном мошенничестве и злоупотреблениях использовался для преследования парсеров, получающих доступ к данным на сайтах после отзыва авторизации, как в случае с LinkedIn против HiQ. Парсинг полностью общедоступного сайта, такого как Indeed, безопаснее.
Хотя большинство парсеров не столкнутся с юридическими проблемами при сборе разумных объемов общедоступных данных в совокупности, на всякий случай обязательно проконсультируйтесь с адвокатом по поводу вашего конкретного случая использования и юрисдикции!
Этика
Помимо чистой законности, важно очищать данные с этической точки зрения. Вот несколько советов:
Собирайте только те данные, которые вы можете законно использовать. Парсинг вакансий, на которые вы планируете претендовать, — это нормально; собирать миллионы резюме только потому, что вы можете, неэтично.
Используйте регулирование и прокси-серверы, чтобы избежать перегрузки серверов и снижения производительности сайта. Атака в стиле DDoS, вызванная чрезмерными запросами на парсинг, неэтична.
Соблюдайте директивы robots.txt, которые запрещают парсинг на определенных сайтах. Например, и LinkedIn, и Monster просят не парсить данные.
Никогда не пытайтесь без разрешения собирать личные данные, такие как профили пользователей или резюме.
Не переиздавайте систематически контент, защищенный авторским правом, в больших масштабах без лицензии на это.
В общем, чистите добросовестно. Indeed — это общедоступный веб-сайт, который не запрещает сбор данных из файла robots.txt, но обязательно собирайте данные с соблюдением этических норм. Теперь давайте посмотрим, как царапать!
Парсинг списков Indeed с помощью Python и Selenium
Селен — это популярная платформа автоматизации браузера для очистки веб-страниц Python. Программно управляя реальным веб-браузером, таким как Chrome, вы можете копировать действия пользователя, такие как поиск, нажатие элементов и извлечение данных с загруженных страниц.
Давайте рассмотрим скрипт Python для сбора результатов заданий на Indeed с помощью Selenium:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import json
driver = webdriver.Chrome()
driver.get(‘https://www.indeed.com‘)
# Search for jobs
search_box = driver.find_element(By.NAME,‘q‘)
search_box.send_keys(‘data scientist‘)
location_box = driver.find_element(By.NAME, ‘l‘)
location_box.send_keys(‘san francisco‘)
search_box.submit()
# Wait for results to load
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, ‘mosaic-provider-jobcards‘))
)
# Extract data from each result
results = []
job_cards = driver.find_elements(By.CLASS_NAME,‘jobsearch-SerpJobCard‘)
for job in job_cards:
title = job.find_element(By.CLASS_NAME, ‘title‘).text
company = job.find_element(By.CLASS_NAME, ‘company‘).text
location = job.find_element(By.CLASS_NAME, ‘location‘).text
summary = job.find_element(By.CLASS_NAME, ‘summary‘).text
post_date = job.find_element(By.CLASS_NAME, ‘date‘).text
result = {
‘title‘: title,
‘company‘: company,
‘location‘: location,
‘summary‘: summary,
‘post_date‘: post_date
}
results.append(result)
# Save data
with open(‘results.json‘, ‘w‘) as f:
json.dump(results, f)
driver.quit()
Вот некоторые ключевые шаги в этом сценарии:
Мы используем
webdriver.Chrome()
Драйвер Selenium для запуска Chrome без управления.Условия поиска вводятся и отправляются на главной странице Indeed.
Мы ждем
#mosaic-provider-jobcards
элемент для загрузки перед извлечением данных.Мы находим элементы по имени класса и извлекаем текст из каждого в словарь.
Наконец, структурированные результаты сохраняются в файл JSON.
Это позволяет реализовать основы очистки списков Indeed с помощью Selenium. Если вы хотите пойти дальше:
Очистите дополнительные поля, такие как зарплата, описание, рейтинг компании и т. д.
Используйте явные ожидания, например
WebDriverWait
вместо time.sleep() для надежности.Используйте селекторы CSS и XPath для точного расположения элементов.
Экспортируйте очищенные данные в базу данных или конечную точку API, а не только в файлы JSON.
В целом, Selenium предоставляет удобный способ автоматизации браузеров для очистки веб-страниц. Но с большими объемами страниц могут возникнуть проблемы из-за снижения производительности браузера. Для крупномасштабной очистки мы рекомендуем…
Действительно, масштабирование с помощью Scrapy
Scrapy — это специальная платформа веб-скрапинга для Python, оптимизированная для быстрого и эффективного сканирования множества страниц.
По сравнению с Selenium Scrapy имеет некоторые преимущества:
Устраняет накладные расходы на запуск реальных браузеров — делает запросы напрямую.
Асинхронная архитектура одновременно обрабатывает много страниц быстрее.
Встроенная поддержка нумерации страниц, регулирования, кэширования и многого другого.
Больше гибкости для сложной логики очистки с помощью настраиваемых обратных вызовов.
Вот пример действительно паука с Scrapy:
import scrapy
class IndeedSpider(scrapy.Spider):
name = ‘indeed‘
allowed_domains = [‘indeed.com‘]
def start_requests(self):
yield scrapy.Request(
url=‘https://www.indeed.com‘,
callback=self.search
)
def search(self, response):
search_box = response.css(‘[name=q]‘)
search_box.set(‘data scientist‘)
location_box = response.css(‘[name=l]‘)
location_box.set(‘san francisco‘)
search_box.xpath(‘./following::button[1]‘).click()
yield scrapy.Request(
url=response.url,
callback=self.parse_results,
)
def parse_results(self, response):
for job in response.css(‘#mosaic-provider-jobcards .jobsearch-SerpJobCard‘):
yield {
‘title‘: job.css(‘.title::text‘).get(),
‘company‘: job.css(‘.company::text‘).get(),
# Other fields scraped
}
next_page = response.css(‘.pagination a::attr(href)‘).get()
if next_page:
yield scrapy.Request(
response.urljoin(next_page),
callback=self.parse_results
)
Ключевые моменты:
Правила вроде
allowed_domains
иrobots.txt
соответствие обеспечивает безопасное соскабливание.Мы находим поля формы с помощью CSS и имитируем отправку поиска.
Ассоциация
parse_results()
Метод возвращает очищенные данные из каждого листинга.Переход по ссылкам на страницы позволяет выполнять парсинг по нескольким страницам.
По умолчанию задания экспортируются в структурированный JSON.
Для еще более масштабных обходов мы можем настроить следующее в settings.py
:
DOWNLOAD_DELAY
иAUTOTHROTTLE_ENABLED
для регулирования запросов.HTTPCACHE_ENABLED
для кэширования запросов и минимизации попаданий.RETRY_TIMES
чтобы повторить неудачную загрузку страницы.RANDOM_PROXY
из пула, чтобы предотвратить блокировку IP-адресов.
Благодаря всем своим встроенным функциям Scrapy идеально подходит для масштабного сканирования списков вакансий Indeed. Но это только первый шаг: чтобы получить ценную информацию, нам необходимо проанализировать данные.
Анализ списков вакансий Indeed с помощью BigQuery и Python
После очистки данные о вакансиях Indeed становятся более полезными, если их структурировать и проанализировать в большом масштабе. Некоторые популярные варианты хранения включают в себя:
- Базы данных SQL например Postgres для структурированных запросов
- Базы данных NoSQL например MongoDB для гибкого хранения JSON
- Хранилища данных например BigQuery для крупномасштабного анализа
Давайте рассмотрим пример рабочего процесса для анализа наших скопированных списков с помощью BigQuery:
После очистки загрузите результаты JSON в набор данных BigQuery. Scrapy Cloud прекрасно интегрируется здесь.
Создайте таблицу с сопоставлением схемы, например
title STRING, company STRING, location STRING
и так далееЗапустите SQL-запросы для анализа:
-- Top companies hiring
SELECT company, COUNT(1)
FROM `indeed.listings`
GROUP BY company
ORDER BY COUNT(1) DESC
LIMIT 10
-- Average salary by job title
SELECT title, AVG(salary)
FROM `indeed.listings`
GROUP BY title
ORDER BY AVG(salary) DESC
- Визуализируйте аналитическую информацию с помощью студии данных или подключите BigQuery к инструментам Python, таким как Pandas, для дальнейшего анализа:
import pandas as pd
df = pd.read_gbq(‘‘‘
SELECT title, AVG(salary) as avg_salary
FROM `indeed.listings`
GROUP BY title
ORDER BY avg_salary DESC
‘‘‘)
# Visualize average salary by title
ax = df.plot.barh(x=‘title‘, y=‘avg_salary‘, rot=0)
Это дает представление о мощной аналитике, которую можно получить с помощью собранных данных Indeed. Ключевым моментом является преобразование его в такой формат, как хранилище данных, которое позволяет использовать как SQL-запросы для структурированного анализа, так и подключение к возможностям Python по визуализации и моделированию.
Скрапинг легально и этично
В заключение давайте резюмируем некоторые ключевые рекомендации по юридическим и этическим практикам при парсинге Indeed или любого веб-сайта:
Уважать авторское право – Собирайте только систематически чисто фактические данные, а не содержательный оригинальный контент. Юридический приоритет в этой новой области все еще устанавливается.
Следуйте условиям обслуживания – Соблюдайте Условия обслуживания Indeed и воздерживайтесь от чрезмерного парсинга, который может снизить производительность сайта.
Ограничить сбор данных – Собирайте только минимальные данные, необходимые для ваших целей, вместо того, чтобы пылесосить все списки.
Обезличить персональные данные – Избегайте очистки идентифицируемых резюме или профилей пользователей, которые могут нарушать правила конфиденциальности.
Проверьте robots.txt – Файл robots.txt компании Indeed разрешает парсинг, но некоторые сайты, такие как LinkedIn, запрещают это.
Использовать регулирование – Ограничьте скорость запросов и включите задержки, чтобы минимизировать нагрузку на сервер. Распределите нагрузку по IP-адресам.
Парсинг в рамках этих этических границ может предоставить Indeed полезную информацию, не причиняя вреда сайту или его пользователям. Мы надеемся, что это руководство поможет вам вооружиться инструментами и этическим мышлением, чтобы ответственно относиться к парсингу!