Как спарсить все страницы и записать все в json?

Написал код для парсинга сайта по аренде автомобилей (rentride.ru). Проблема в том, что парсер не считывает все страницы, либо идет какой-то бесконечный цикл + не все записывается в json (max 3 строки). Ниже прикладываю мой код, HTML-разметку пагинации и скрины результата парсинга.

Вот код парсера:

import requests
from bs4 import BeautifulSoup
import json
from time import sleep


data_dict = []
url = 'https://rentride.ru/arendovat/moskva/'
params = {'page': 1}
pages = 23
n = 1

while params['page'] <= pages:
sleep(1)
response = requests.get(url, params=params)
soup = BeautifulSoup(response.text, 'lxml')
infos = soup.find_all('div', class_='vehicle-card-vertical-body car-info-body')

for n, i in enumerate(infos, start=n):
    name = i.find('h4', class_='title-car').text.strip()
    stars = i.find('div', class_='rating-value').text.strip()
    comments = i.find('div', class_='car-review-count').text.strip()
    price = i.find('div', class_='car-price-info').text.strip()
    print(f'{n}: {name} цена:{price} с оценкой {stars} и количеством отзывов:{comments}')

    last_page_num = int(soup.find_all('a', class_='no-decoration pagination-number-item')[0].text)
    pages = last_page_num if pages < last_page_num else pages
    params['page'] +=1

data = {
    'car': name,
    'price': price,
    'stars': stars,
    'comments': comments,
    }

data_dict.append(data)

with open('data_2.json', 'w') as json_file:
    json.dump(data_dict, json_file, indent=5)

HTML-разметка пагинации:

<div total="450" paramsreq="[object Object]" class="pagination"><div class="show-more-button">
        Показать ещё
    </div> <div class="pagination-number"><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=1" class="no-decoration pagination-number-item active">
        1
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=2" class="no-decoration pagination-number-item">
        2
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=3" class="no-decoration pagination-number-item">
        3
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=4" class="no-decoration pagination-number-item">
        4
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=5" class="no-decoration pagination-number-item">
        5
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=6" class="no-decoration pagination-number-item">
        6
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=7" class="no-decoration pagination-number-item">
        7
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=..." class="no-decoration pagination-number-item other">
        ...
    </a><a href="/arendovat/moskva/?min_year=2010&amp;max_year=2022&amp;page=23" class="no-decoration pagination-number-item">
        23
    </a></div></div>

Результат парсинга: введите сюда описание изображения

Подскажите, пожалуйста, где недочеты в коде?


Ответы (1 шт):

Автор решения: n1tr0xs

Максимальный номер страницы достаточно спарсить один раз, он ведь не меняется.

import requests
from bs4 import BeautifulSoup
import json
from time import sleep


data_dict = []
url = 'https://rentride.ru/arendovat/moskva/'
n = 1
params = {'page': 1}

response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
last_page_num = int(soup.find_all('a', class_='pagination-number-item')[-1].text) # один раз узнали какая страница последняя..

for page_num in range(1, last_page_num-1): # ..и просто итерируемся до неё
    sleep(1)
    params['page'] = page_num
    response = requests.get(url, params=params)
    soup = BeautifulSoup(response.text, 'lxml')
    infos = soup.find_all('div', class_='vehicle-card-vertical-body car-info-body')

    for n, i in enumerate(infos, start=n):
        name = i.find('h4', class_='title-car').text.strip()
        stars = i.find('div', class_='rating-value').text.strip()
        comments = i.find('div', class_='car-review-count').text.strip()
        price = i.find('div', class_='car-price-info').text.strip()
        print(f'{n}: {name} цена:{price} с оценкой {stars} и количеством отзывов:{comments}')

        data = {
            'car': name,
            'price': price,
            'stars': stars,
            'comments': comments,
        }

        data_dict.append(data)

with open('data_2.json', 'w') as json_file:
    json.dump(data_dict, json_file, indent=5)
→ Ссылка