Цель заключается в сборе вакансий с hh.ru (русская платформа поиска работы), а также сопутствующей информации по предотвращению мошенничества, сбору резюме и других материалов.
Основные Проблемы и Решения
Меры Против Скрапинга
hh.ru внедряет различные меры против скрапинга, чтобы ограничить боты или скрапинг. Некоторые из них включают:
-
Ограничение Запросов: hh.ru накладывает временные ограничения на частоту запросов. После нескольких быстрых запросов может быть наложено ограничение. Это может привести к задержкам между запросами, обычно от нескольких минут до часа, или даже блокировке, если частота слишком высокая.
-
Ограничение на Пагинацию: Нет строгого лимита на количество страниц, которые можно скрапить. Однако, на практике, скрапинг нескольких страниц (например, 3-5) является типичным, чтобы избежать срабатывания мер защиты от скрапинга. Каждая страница обычно содержит до 30 вакансий, поэтому 3-5 страниц обычно достаточно для сбора приличного объема данных.
-
Куки и Заголовки: Если вы вставляете куки для вашей сессии, убедитесь, что не нажимаете “Enter” после вставки. Удаление последней пары ключ-значение может помочь обойти проблемы, которые могут возникнуть из-за недействительных куки.
Пояснение Ключевых Моментов
API Вакансий
hh.ru предоставляет API, которое можно использовать для поиска вакансий по ключевым словам (например, “IT”, “Кибербезопасность” и т. д.) и местоположению. API не накладывает строгих ограничений на количество страниц, однако слишком быстрое скрапирование многих страниц может привести к блокировке или CAPTCHам.
API Вакансий:
https://api.hh.ru/vacancies
Анализ Ссылки на Вакансии:
https://hh.ru/search/vacancy?text=IT+%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D0%B8&area=1&experience=between_1_and_3&salary=100000&items_on_page=20
Анализ Параметров:
keywords = "разработчик, кибербезопасность, IT"
city_name = "Москва" # Можно указать 'Москва' или 'Москва и МО'
Код Города:
city_code = get_citycode(city_name)
def get_citycode(city_name):
response = requests.get('https://api.hh.ru/areas')
city_data = response.json()
# Ищем в каждом регионе города
for region in city_data:
# Если город найден в регионе, возвращаем его ID
for area in region.get('areas', []):
if area['name'] == city_name:
return area['id']
return None
Структура Конкатенации JSON API:
for region in city_data:
for area in region.get('areas', []):
if area['name'] == city_name:
return area['id']
for region in city_data:
for area in region.get('areas', []):
if area['name'] == city_name:
return area['id']
for job in job_listings:
job_name = job['name']
salary = job['salary']
employer_name = job['employer']['name']
area_name = job['area']['name']
job_url = job['alternate_url']
Цикл и Извлечение:
job_listings = get_job_list(keywords, city_name)
# Выводим информацию о найденных вакансиях
if job_listings:
for job in job_listings: # This is the loop that iterates through job listings
job_name = job['name']
salary = job['salary']
employer_name = job['employer']['name']
area_name = job['area']['name']
job_url = job['alternate_url'] # URL вакансии
# Зарплата (если указана)
salary_from = salary.get('from', 'Не указано') if salary else 'Не указано'
salary_to = salary.get('to', 'Не указано') if salary else 'Не указано'
salary_currency = salary.get('currency', 'Не указана') if salary else 'Не указана'
# Другие дополнительные данные
employment_type = job['employment']['name'] if 'employment' in job else 'Не указано'
experience_required = job['experience']['name'] if 'experience' in job else 'Не указано'
skills=", ".join(job['key_skills']) if 'key_skills' in job else 'Не указаны'
# Выводим все найденные детали вакансии
print(f"Вакансия: {job_name}")
print(f"Зарплата: от {salary_from} до {salary_to} {salary_currency}")
print(f"Компания: {employer_name}")
print(f"Город: {area_name}")
print(f"Тип занятости: {employment_type}")
print(f"Требуемый опыт: {experience_required}")
print(f"Навыки: {skills}")
print(f"Ссылка на вакансию: {job_url}")
print("-" * 40)
Включённый Исходный Код:
https://github.com/Excalibra/scripts/blob/main/d-python/hh.ru_demo.py
import os
import requests
import json
from openpyxl import Workbook
from datetime import datetime
# Your existing get_citycode and get_job_list functions should already be defined in your script.
# Make sure they are present in the script or imported from another module.
# For example, let's assume this is part of your script:
def get_citycode(city_name):
response = requests.get('https://api.hh.ru/areas')
city_data = response.json()
# Ищем в каждом регионе города
for region in city_data:
# Если город найден в регионе, возвращаем его ID
for area in region.get('areas', []):
if area['name'] == city_name:
return area['id']
return None
def get_job_list(keywords, city_name):
city_code = get_citycode(city_name)
if city_code is None:
print(f"Город '{city_name}' не найден.")
return []
url = "https://api.hh.ru/vacancies"
params = {
'text': keywords, # Ключевые слова для поиска вакансий
'area': city_code, # ID города
'page': 0, # Стартовая страница
'per_page': 10, # Количество вакансий на странице
}
response = requests.get(url, params=params)
data = response.json()
return data['items']
# Your DataToExcel class remains the same.
class DataToExcel:
@staticmethod
def save_to_excel(workbook, hhru_json):
# Load the hh.ru JSON data
with open(hhru_json, 'r', encoding='utf-8') as f:
hhru_json = json.load(f)
worksheet = workbook.create_sheet(title="Job Listings")
# Define the column titles
titles = [
'Job Title', 'Skills', 'Experience', 'Salary From', 'Salary To', 'Currency',
'Company', 'Employment Type', 'Experience Required', 'City', 'Job URL'
]
# Write the titles in the first row
for col, title in enumerate(titles, start=1):
worksheet.cell(row=1, column=col, value=title)
# Extract job listings from the JSON data
job_data_list = hhru_json.get('items', [])
row = 2 # Start from the second row for data
for job in job_data_list:
worksheet.cell(row=row, column=1, value=job.get('name', 'N/A'))
worksheet.cell(row=row, column=2, value=", ".join(job.get('key_skills', [])))
worksheet.cell(row=row, column=3, value=job.get('experience', {}).get('name', 'N/A'))
# Handle salary data
salary = job.get('salary', {})
salary_from = salary.get('from', 'N/A') if salary else 'N/A'
salary_to = salary.get('to', 'N/A') if salary else 'N/A'
salary_currency = salary.get('currency', 'N/A') if salary else 'N/A'
worksheet.cell(row=row, column=4, value=salary_from)
worksheet.cell(row=row, column=5, value=salary_to)
worksheet.cell(row=row, column=6, value=salary_currency)
worksheet.cell(row=row, column=7, value=job.get('employer', {}).get('name', 'N/A'))
worksheet.cell(row=row, column=8, value=job.get('employment', {}).get('name', 'N/A'))
worksheet.cell(row=row, column=9, value=job.get('experience', {}).get('name', 'N/A'))
worksheet.cell(row=row, column=10, value=job.get('area', {}).get('name', 'N/A'))
worksheet.cell(row=row, column=11, value=job.get('alternate_url', 'N/A'))
row += 1 # Move to the next row
# Save the workbook to a file
save_xlsx = os.path.join(
os.path.expanduser("~"), "Desktop", f"hhru_jobs_{datetime.now().strftime('%Y-%m-%d')}.xlsx"
)
workbook.save(save_xlsx)
print(f"Job listings have been saved to: {save_xlsx}")
# Example function that saves the job data and calls the Excel export function
def save_hhru_data_to_excel():
# Ensure get_job_list is available here.
job_listings = get_job_list("разработчик, кибербезопасность, IT", "Москва")
# Save the job listings to a JSON file
hhru_json_path = os.path.join(os.path.expanduser("~"), "Desktop", f"hhru_jobs_{datetime.now().strftime('%Y-%m-%d')}.json")
with open(hhru_json_path, 'w', encoding='utf-8') as f:
json.dump({"items": job_listings}, f, ensure_ascii=False, indent=4)
# Create a new workbook and save the data to Excel
workbook = Workbook()
workbook.remove(workbook.active) # Remove the default sheet
DataToExcel.save_to_excel(workbook, hhru_json_path)
# Call the function to save the job listings to Excel
save_hhru_data_to_excel()
Source link
lol