Как спарсить все страницы сайта , загружая только одну страницу
Сайт https://www.livelib.ru/reader/LushbaughPizzicato/read/ автоматически подгружает 20 книг, если нажать "показать еще" он подгрузит еще 20 книг, как можно сделать, чтобы подгрузились сразу все книги?
И потом этот результат обработать с помощью beautifulsoup?
Как я понимаю в Network , с помощью getcountbooks в header: content-legth 20 задается количество загружаемых книг, но как передать это на сайт и изменить 20 на другое число я не понимаю.
Пс заранее спасибо)
Ответы (2 шт):
Вот пример с моего бота. За формат прошу не пинать. через пару часу буду у ноута, отформатирую как принято.
В данном примере парсится вес табака, что есть в наличии. Если обнаруживает пагинацию - берет ссылку на след страничку и рекурсивно работает.
def __get_weight_kalyan_od_ua(url) -> set:
weight = set()
logger.info(f'Переходим по {url} и парсим её')
try:
soup = __get_soup(url) #получаем все тело сайта
except:
return weight #если ошибка при запросе, возвращаем пустой обьект
logger.info(f'Получаем ссылку на следующую страницу с табаками в категории')
next_page = __parse_next_page(soup, 'ul', 'class', 'pagination') #парсим элемент с пагинацией
next_page = next_page.find('a', text='>') if next_page else next_page #если есть кнопка след страницы, сохраняем ее иначе None
logger.info(f'Парсим все продукты на странице')
products = __parse_products(soup, 'a', 'class', 'products__item-title') #список табаков
logger.info(f'Проходим по каждому продукту')
for product in products:
logger.info(f'Парсим есть ли он в наличии, если нет - переходим к следующему')
if not __parse_available(product.parent.parent, 'mark', 'class', 'products__item-mark--nocatch'):
logger.info(f'Пропускаем')
continue
logger.info(f'Парсим вес продукта из названия')
weight.add(__parse_weight(product.text))
logger.info(f'Пока есть следующая страница, повторяем процес парсинга веса')
if next_page: # если есть элемент след страницы
weight.update(__get_weight_kalyan_od_ua(next_page['href'])) #рекурсивно вызываем функцию ещё раз
return weight
Можно в тело запроса подставить количество возвращаемых записей через поле per_page.
По умолчанию, там 20 объектов, в качестве примера подставил туда 100 и пришло 54 элемента, т.е. все
Пример:
import requests
url = 'https://www.livelib.ru/reader/LushbaughPizzicato/read/listview/smalllist'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0',
'X-Requested-With': 'XMLHttpRequest',
}
data = {
'page_no': 1,
'per_page': 100,
'is_new_design': "ll2019",
'is_prev': "false"
}
rs = requests.post(url, data=data, headers=headers)
print(rs)
data_json = rs.json()
object_ids = data_json['object_ids']
print(len(object_ids), object_ids)
# 54 [1000518262, 1002753859, 1000330921, ..., 1000593383, 1002885672]
Думаю, имеет смысл рассказать как это написал.
- Нашел запрос, отправленный при клике на кнопку "показать еще"
- Посмотрел на тело запроса

- В заголовках запроса посмотрел на
Content-Type, от этого зависит какой атрибут использовать для отправки тела запроса:data,jsonилиfiles. Аx-www-form-urlencodedэтоdata
- Добавил в заголовок запроса
User-AgentиX-Requested-With, чтобы сервер принял его и вернул ожидаемыйjson