С Новым годом! Форум программистов, компьютерный форум, киберфорум
Python
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 09.12.2020
Сообщений: 8

Парсинг сайта по вакансиям на python

26.01.2023, 17:02. Показов 3232. Ответов 16

Студворк — интернет-сервис помощи студентам
Всем привет, пробую себя в парсинге впервые, до определенного момента все шло хорошо, но когда нужно вывести названия вакансий в виде текста, мне приходит ответ "200", хотя должны появится названия вакансий с первой страницы сайта, над которым я работаю, если кто-то знает, в чем проблема буду очень благодарна)

Вот код первого файла "main.py":

Python
1
2
3
from headhunter import extract_max_page, extract_hh_jobs
max_page = extract_max_page()
extract_hh_jobs(max_page)
код второго файла headhunter.py:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import requests
from bs4 import BeautifulSoup
ITEMS = 100
URL = f'https://hh.ru/search/vacancy?text=python&items_on_page={ITEMS}'
headers = {
  'Host': 'hh.ru',
  'User-Agent': 'Safari',
  'Accept': '*/*',
  'Accept-Encoding':'gzip, deflate, br',
  'Connection': 'keep-alive'
}
def extract_max_page():
  hh_request=requests.get(URL, headers=headers)
  hh_soup = BeautifulSoup (hh_request.text,'html.parser')
  pages = []
  paginator = hh_soup.find_all("span", {'class':'pager-item-not-in-short-range'}) 
  for page in paginator:
    pages.append(int(page.find('a').text))
  return pages[-1]
def extract_hh_jobs(last_page):
  jobs = []
  #for page in range (last_page):
  result = requests.get(f'{URL}&page=0', headers=headers)
  print(result.status_code)
  soup = BeautifulSoup (result.text,'html.parser')
  results = soup.find_all('div', {'class':'serp-item__title'})
  for result in results:
    print(result.find('a').text)
    
  return jobs
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.01.2023, 17:02
Ответы с готовыми решениями:

Python 3,парсинг сайта
Вот получил данные,но не знаю как склеить в 1 строку.Само число не могу вытащить

Парсинг сайта на Python
1. Python 3.9 2. ОС Windows 10 x64 3. Версии используемых библиотек C:\Users\Artur>pip list Package Version ------------------...

Парсинг сайта на python
Здравствуйте, хотел с помощью программы доставать данные из сайта Олимп Трейд, а именно курс валюты через каждую минуту, но столкнулся с...

16
1 / 1 / 0
Регистрация: 27.01.2023
Сообщений: 6
27.01.2023, 12:31
cybers_, Добрый день. Попробую помочь!
Проблема в том, что вы добавляете номер страницы к URL-адресу не в том месте. В 'extract_hh_jobs' функции вы добавляете '&page=0' в конец URL-адреса, но он должен добавляться в конец URL переменной, которую вы определили ранее.

Вместо этого:
Python
1
result = requests.get(f'{URL}&page=0', headers=headers)
Это должно быть так:
Python
1
result = requests.get(f'{URL}&page={page}', headers=headers)
Кроме того, в 'extract_hh_jobs' функции вы используете results переменную для двух разных целей: сначала для хранения тегов div, а затем для зацикливания тегов. Это вызовет проблему. Вы должны изменить имя переменной одной из двух переменных.

Кроме того, вы используете переменную jobs, но, похоже, ничего к ней не добавляете. В цикле for вы должны добавить result.find('a').text к списку заданий.

Python
1
jobs.append(result.find('a').text)
Наконец, вам нужно будет включить цикл по страницам для извлечения данных с каждой страницы.

Python
1
2
3
4
5
6
for page in range(last_page):
    result = requests.get(f'{URL}&page={page}', headers=headers)
    soup = BeautifulSoup(result.text,'html.parser')
    results = soup.find_all('div', {'class':'serp-item_title'})
    for result in results:
        jobs.append(result.find('a').text)
Это должно выглядеть так:

Python
1
2
3
4
5
6
7
8
9
def extract_hh_jobs(last_page):
    jobs = []
    for page in range(last_page):
        result = requests.get(f'{URL}&page={page}', headers=headers)
        soup = BeautifulSoup(result.text,'html.parser')
        results = soup.find_all('div', {'class':'serp-item_title'})
        for result in results:
            jobs.append(result.find('a').text)
    return jobs
Теперь все должно работать нормально.
1
0 / 0 / 0
Регистрация: 09.12.2020
Сообщений: 8
27.01.2023, 12:56  [ТС]
Вроде бы все поменяла, но результат тот же...я тут добавила еще функцию "extract_job(html)", чтобы получить названия компаний и их местоположение, но не работает(((
Загрузила скрин, вот в текстовом формате:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import requests
from bs4 import BeautifulSoup
ITEMS = 100
URL = f'https://hh.ru/search/vacancy?text=python&items_on_page={ITEMS}'
headers = {
  'Host': 'hh.ru',
  'User-Agent': 'Safari',
  'Accept': '*/*',
  'Accept-Encoding':'gzip, deflate, br',
  'Connection': 'keep-alive'
}
def extract_max_page():
  hh_request=requests.get(URL, headers=headers)
  hh_soup = BeautifulSoup (hh_request.text,'html.parser')
  pages = []
  paginator = hh_soup.find_all("span", {'class':'pager-item-not-in-short-range'}) 
  for page in paginator:
    pages.append(int(page.find('a').text))
  return pages[-1]
def extract_job(html):
  title=html.find('a').text
  link =html.find('a').text ['href']
  company = html.find('div', {'class': 'vacancy-serp-item__meta-info-company'}).text
  company = company.strip()
  location = html.find('span', {'data-qa':'vacancy-serp__vacancy-address'}).text
  location = location.partition(',')[0]
  return {'title':title, 'company': company, 'location': location, 'link':link}
def extract_hh_jobs(last_page):
  jobs = []
  for page in range (last_page):
    print(f'Парсинг страницы {page}')
    result = requests.get(f'{URL}&page={page}', headers=headers)
    print(result.status_code)
    soup = BeautifulSoup (result.text,'html.parser')
    results = soup.find_all('div', {'class':'serp-item__title'})
    for result in results:
      jobs.append(result.find('a').text)
    
  return jobs
Миниатюры
Парсинг сайта по вакансиям на python  
0
1 / 1 / 0
Регистрация: 27.01.2023
Сообщений: 6
27.01.2023, 13:00
Попробуйте изменить строку jobs.append(result.find('a').text) на jobs.append(extract_job(result)). Кроме того, в функции extract_job необходимо использовать html.find('a')['href'] для получения ссылки вместо html.find('a').text['href']
0
0 / 0 / 0
Регистрация: 09.12.2020
Сообщений: 8
27.01.2023, 13:20  [ТС]
Видимо не заработает...
Спасибо за помощь)
Миниатюры
Парсинг сайта по вакансиям на python  
0
1 / 1 / 0
Регистрация: 27.01.2023
Сообщений: 6
27.01.2023, 13:28
cybers_,
Похоже, что веб-сайт, который вы пытаетесь парсить, может иметь некоторые механизмы защиты от очистки, поэтому вы получаете код состояния «200». Некоторые веб-сайты блокируют или ограничивают доступ к своим страницам, если обнаружат, что запросы исходят от скрипта или бота.

Одним из решений этой проблемы является использование метода, называемого «веб-скрапинг с помощью безголового браузера», который позволяет вам взаимодействовать с веб-сайтом, как если бы вы были реальным пользователем, использующим веб-браузер. Это можно сделать с помощью таких инструментов, как Selenium или Puppeteer, которые позволяют программно управлять веб-браузером и обходить механизмы защиты от парсинга.

Другим решением является использование API парсинга веб-страниц, такого как Scrapinghub, который позволяет вам парсить веб-сайты, не беспокоясь о механизмах защиты от парсинга.

В качестве альтернативы вы можете попробовать использовать другой веб-сайт или добавить User-Agentв заголовки, чтобы это выглядело так, как будто вы просматриваете веб-сайт с помощью браузера.
0
0 / 0 / 0
Регистрация: 09.12.2020
Сообщений: 8
27.01.2023, 13:32  [ТС]
В этой части кода, как раз использую User-Agent:
Python
1
2
3
4
5
6
7
headers = {
  'Host': 'hh.ru',
  'User-Agent': 'Safari',
  'Accept': '*/*',
  'Accept-Encoding':'gzip, deflate, br',
  'Connection': 'keep-alive'
}
Или я сделала неправильно?
0
1 / 1 / 0
Регистрация: 27.01.2023
Сообщений: 6
27.01.2023, 13:46
cybers_,
Похоже, проблема в том, что вы не вызываете функцию extract_job() в своей функции extract_hh_jobs(). Вместо этого вы добавляете результат result.find('a').text в список заданий. Попробуйте вместо этого вызвать функцию extract_job() и добавить результат в джоб лист.

Вот пример того, как вы можете вызвать функцию extract_job():
Python
1
2
3
for result in results:
    job = extract_job(result)
    jobs.append(job)
Добавлено через 2 минуты
cybers_, Также попробуйте такой вариант кода.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import requests
from bs4 import BeautifulSoup
 
ITEMS = 100
URL = f'https://hh.ru/search/vacancy?text=python&items_on_page={ITEMS}'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0;Win64) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
}
 
def extract_max_page():
    hh_request = requests.get(URL, headers=headers)
    hh_soup = BeautifulSoup(hh_request.text, 'html.parser')
    pages = []
    paginator = hh_soup.find_all("span", {'class':'pager-item-not-in-short-range'})
    for page in paginator:
        pages.append(int(page.find('a').text))
    return max(pages)
 
def extract_job(html):
    title = html.find('a', {'class': 'bloko-link HH-LinkModifier'}).text
    link = html['href']
    company = html.find('div', {'class': 'vacancy-serp-item__meta-info-company'}).text
    company = company.strip()
    location = html.find('span', {'data-qa':'vacancy-serp__vacancy-address'}).text
    location = location.partition(',')[0]
    return {'title':title, 'company': company, 'location': location, 'link':link}
 
def extract_hh_jobs(last_page):
    jobs = []
    for page in range(1, last_page + 1):
        print(f'Parsing page {page}')
        result = requests.get(f'{URL}&page={page}', headers=headers)
        print(result.status_code)
        soup = BeautifulSoup(result.text, 'html.parser')
        results = soup.find_all('div', {'class':'vacancy-serp-item'})
        for result in results:
            jobs.append(extract_job(result))
    return jobs
 
last_page = extract_max_page()
jobs = extract_hh_jobs(last_page)
print(jobs)
Добавлено через 3 минуты
Обновлен User-Agent заголовок до действительного, который обычно используется веб-браузерами.
Исправлена extract_max_page​​функция правильного извлечения максимального номера страницы.
В конце добавил оператор печати для печати jobs списка.

По мелочи, но, может, заработает.
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,664
Записей в блоге: 29
27.01.2023, 13:49
cybers_, hyrodev, на панельке ответа есть кнопочки с названиями языков, ткните на питон и свой код вставляйте между появившимися тегами
1
0 / 0 / 0
Регистрация: 09.12.2020
Сообщений: 8
27.01.2023, 15:14  [ТС]
Прогнала код, который вы отправили, теперь в консоли выводится с 1 по 4 страницы)
Миниатюры
Парсинг сайта по вакансиям на python  
0
1 / 1 / 0
Регистрация: 27.01.2023
Сообщений: 6
27.01.2023, 15:36
cybers_,
Отлично, похоже проблема с невозможностью извлечь максимальное количество страниц решена. Теперь вы можете использовать эту extract_max_page() функцию, чтобы получить общее количество страниц и использовать это число для извлечения заданий со всех страниц.


Вот переписанный код (полностью), который должен работать:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import requests
from bs4 import BeautifulSoup
 
ITEMS = 100
URL = f'https://hh.ru/search/vacancy?text=python&items_on_page={ITEMS}'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0;Win64) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
}
 
def extract_max_page():
    hh_request = requests.get(URL, headers=headers)
    hh_soup = BeautifulSoup(hh_request.text, 'html.parser')
    pages = []
    paginator = hh_soup.find_all("span", {'class':'pager-item-not-in-short-range'})
    for page in paginator:
        pages.append(int(page.find('a').text))
    return pages[-1]
 
def extract_job(html):
    title = html.find('a', {'class':'bloko-link HH-LinkModifier'}).text.strip()
    link = html.find('a', {'class':'bloko-link HH-LinkModifier'})['href']
    company = html.find('div', {'class': 'vacancy-serp-item__meta-info-company'}).text.strip()
    location = html.find('span', {'data-qa':'vacancy-serp__vacancy-address'}).text.strip()
    return {'title':title, 'company': company, 'location': location, 'link':link}
 
def extract_hh_jobs(last_page):
    jobs = []
    for page in range(last_page+1):
        print(f'Parse page {page}')
        result = requests.get(f'{URL}&page={page}', headers=headers)
        print(result.status_code)
        soup = BeautifulSoup(result.text,'html.parser')
        results = soup.find_all('div', {'class':'vacancy-serp-item'})
        for result in results:
            jobs.append(extract_job(result))
    return jobs
 
last_page = extract_max_page()
jobs = extract_hh_jobs(last_page)
print(jobs)
0
0 / 0 / 0
Регистрация: 09.12.2020
Сообщений: 8
27.01.2023, 16:35  [ТС]
Забавно получается, но результат тот же, как и в предыдущем скрине...Видимо придется пробовать что-то другое, как вы и писали выше
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,664
Записей в блоге: 29
27.01.2023, 17:06
Цитата Сообщение от hyrodev Посмотреть сообщение
«веб-скрапинг с помощью безголового браузера»,
что что? ты что бот чтоли? откуда ответы копируешь, из гпт?
0
 Аватар для rim41
1045 / 313 / 78
Регистрация: 16.03.2020
Сообщений: 954
29.01.2023, 05:40

Не по теме:

Welemir1, мб на русский гугл переводчиком переводит? Я б заманался все комментарии удалять из кода гпт

0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,664
Записей в блоге: 29
29.01.2023, 09:07
rim41, просто не первый же новичок тут, который дает ответы по пунктам и с плохим переводом на русский. Подозрительно
0
 Аватар для rim41
1045 / 313 / 78
Регистрация: 16.03.2020
Сообщений: 954
29.01.2023, 09:09
Welemir1, Ну оно вполне возможно что нейронкой генерируют ответы, удобный фарм репутации. Другое дело, что даже не читают и не проверяют полезность ответа...
0
 Аватар для OlegChe
73 / 55 / 25
Регистрация: 12.07.2014
Сообщений: 216
01.02.2023, 13:00
По вашему коду, вы выполняете запрос на сайт hh.ru, используя библиотеку requests, после чего парсите HTML-страницу с помощью BeautifulSoup. В вашей функции extract_hh_jobs вы выполняете запрос только для первой страницы (&page=0) и выводите статус кода ответа, а затем выводите текст тайтлов вакансий.

Так как статус код ответа равен 200, это означает, что ваш запрос был успешным и сервер вернул HTML-страницу. Поэтому проблема может быть связана с неправильным парсингом HTML-страницы с помощью BeautifulSoup.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.02.2023, 13:00
Помогаю со студенческими работами здесь

Парсинг сайта на python
Здравствуйте! Стоит задача запарсить сайт яндекс.музыки Нужно чтобы приходила ссылка на трек из чартов Не очень понимаю как это можно...

Парсинг данных с сайта с авторизацией на Python
Здравствуйте! Я новичок, пишу курсовую и пытаюсь сделать парсер на Python для сайта на котором нужно заполнить форму что бы получить...

Парсинг на Python динамического элемента из POST запроса сайта
import requests from bs4 import BeautifulSoup songsNameList = url = f"https://top-radio.ru/web/russkij-xit" q =...

Парсинг генерируемого массива данных с сайта в Excel на Python
Не могу сообразить как сделать, чтобы запись переменных с каждой итерацией переносилась на новую строку таблицы, есть ли способ это...

Организовать поиск по вакансиям с использованием подпрограмм
Программа, организующая ввод и сохранение в бинарном типизированном файле данных о свободных вакансиях на предприятии. Организовать поиск...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru