При извлечении контента с веб-сайта кажется, что «&» в URL-адресе игнорируется

Я настроил веб-скребок и теперь пытаюсь добавить поддержку нумерации страниц. URL-адрес изменяется, как и ожидалось, при переходе на следующую страницу, и к URL-адресу добавляется «&page=X», где X — это номер страницы.

Когда страниц больше нет, увеличение номера страницы в URL-адресе не приводит к ошибке 404. Вместо этого добавляется новый тег с определенным текстом, и этот текст я собираюсь использовать, чтобы определить, что функция может остановиться.

Однако, когда я передаю URL-адрес с '&page=X' (используя (requests_html) HTMLSession), он возвращает содержимое первой страницы, как если бы я даже не передал свойство &page=x, что, я думаю, означает, что HTMLSession либо игнорирует все после & или происходит что-то еще, чего я не понимаю.

Пробовал пример из документации, но не получилось.

r = session.get('https://reddit.com')
for html in r.html:
  print(html)

<HTML url='https://www.reddit.com/'>
<HTML url='https://www.reddit.com/?count=25&after=t3_81puu5'>
<HTML url='https://www.reddit.com/?count=50&after=t3_81nevg'>
<HTML url='https://www.reddit.com/?count=75&after=t3_81lqtp'>

(PS! Это не Reddit, который я пытаюсь очистить).

URL: https://www.finn.no/car/used/search.html?model=1.8078.2000555 и страницы добавляются с &page=X после

Может кто-нибудь мне помочь? Я использую fake_useragent для генерации случайного заголовка.

🤔 А знаете ли вы, что...
В Python есть среды разработки, такие как Jupyter Notebook, которые упрощают работу с данными и исследованиями.


1
55
1

Ответ:

Решено

Да, как вы заметили, 404 нет, когда страница доходит до конца, страница просто показывает вам случайное объявление.

Однако мы можем определить это, проанализировав сами данные. Если на странице больше нет объявлений, значит предыдущая страница была последней.

Ниже я подготовил пример функции. Он принимает идентификатор модели автомобиля в качестве параметра и извлекает все URL-адреса объявлений со всех страниц.

Он использует библиотеку requests (не requests_html) для получения страницы и BeautifulSoup для извлечения JSON с рекламными данными.

import json

import requests
from bs4 import BeautifulSoup

HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                         'AppleWebKit/537.36 (KHTML, like Gecko) '
                         'Chrome/111.0.0.0 Safari/537.36'}


def find_all_car_urls_for_model(model: str) -> list[str]:
    page_number = 1
    all_car_urls = []
    with requests.Session() as sess:
        # set new session and cookies
        _ = sess.get('https://www.finn.no/', headers=HEADERS)

        # iterate over pages
        while True:  
            r = sess.get(
                'https://www.finn.no/car/used/search.html',
                params = {
                    'page': page_number,
                    'sort': 'PUBLISHED_DESC',
                    'model': model,
                },
                headers=HEADERS,
            )

            # extract data JSON from page
            soup = BeautifulSoup(r.text, features = "html.parser")
            extracted_json = json.loads(soup.find('script', id='__NEXT_DATA__').text)

            found_car_urls = [
                ad['ad_link'] for ad 
                in extracted_json['props']['pageProps']['search']['docs']
            ]
            if found_car_urls:
                print(f'Found {len(found_car_urls)} car URLs on page {page_number}')
                all_car_urls.extend(found_car_urls)
                page_number += 1
            else:
                # if no cars were found on page then the search is completed
                break

    return all_car_urls


if __name__ == '__main__':
    result = find_all_car_urls_for_model(model='1.8078.2000555')
    print(result)  # 399 cars - as on page in browser