При парсинге сайта не могу найти нужные теги
Достаточно типовая задача:
Есть сайт (например: https://mirturbaz.ru/russia). Надо спарсить карточки товара/услуг и составить таблицу, содержащую некоторую информацию из этих карточек.
Программу пытался написать тоже типовым образом:
import requests
from bs4 import BeautifulSoup
url = 'https://mirturbaz.ru/russia'
params = {'page': 1}
...
response = requests.get(url, params=params)
...
soup = BeautifulSoup(response.text, 'lxml')
items = soup.find_all('div', class_='card card_big')
Тут у меня и возникает проблема: soup = BeautifulSoup() возвращает пустой список. Если на сайте открыть консоль разработчика, то там теги div класса 'card card_big' видны.
Но BeautifulSoup их не находит. Я сохранил в виде HTML файла response и действительно, там нет никаких карточек.
Я подозреваю, что response = requests.get(url, params=params) только некий "исходный вариант" странички. А для того, что бы он превратился в рабочий, нужно выполнить некие скрипты. Подозреваю, что для этого нужно использовать Selenium.
Кто-то может пояснить ситуацию? Где что нужно читать?
Ответы (2 шт):
"а в исходном HTML, который получается requests.get() ничего нет" плохо искали
import requests
from bs4 import BeautifulSoup
url = 'https://mirturbaz.ru/russia'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
items = soup.find_all('section', class_='not-used-camp-card')
for item in items:
name = item.find('a').text.strip()
print(name)
ответ
База отдыха Стрежень
База отдыха Дон
База отдыха Золотые пески
Загородный клуб Астория
Загородный клуб Ёлки
База отдыха Дом Солнца
База отдыха Лазурит
База отдыха Дубовая Роща
База отдыха Донская Миля
База отдыха Дом на Трехречье
База отдыха Лесное озеро
Санаторий Лаба
База семейного отдыха Сибириада
Коттеджный комплекс Светозар
Туристический комплекс Фрегат
База отдыха Березовые дали
База отдыха Золотой лотос
плохо искали
Дело оказалось не в этом.Я вставил в Ваш пример операторы сохранения прочитанной HTML странички:
with open('page1.html', 'w') as f:
print(response.text, file=f)
и запустил их последовательно. Только Ваш пример сохранял в файл page1.html, а мой - в файл page2.html. Разница оказалась очевидной:
$ ls -l
итого 172
-rw-r--r--. 1 lary lary 130337 мар 20 09:31 page1.html
-rw-r--r--. 1 lary lary 35059 мар 20 09:32 page2.html
Т.е. проблема была не в find_all(), а в requests.get()
params = {'page': 1}
response = requests.get(url, params=params)
Я убрал params=params и исправил имя файла для сохранения на page3.html. Результат оказался неожиданным:
ls -l
итого 300
-rw-r--r--. 1 lary lary 130337 мар 20 09:31 page1.html
-rw-r--r--. 1 lary lary 35059 мар 20 09:32 page2.html
-rw-r--r--. 1 lary lary 130337 мар 20 09:34 page3.html
bash-5.1$
Получается, что правильной выборке текста HTML странички каким-то образом мешает параметр params = {'page': 1}. Почему так - я пока не разобрался.
К сожалению, тегов с классом card_big там всё равно нет. А использовать теги с классом not-used-camp-card мне кажется довольно сомнительным.