Перелистывание страниц с помощью парсера

Нужно написать цикл для того что бы парсер собирал данные со всех страниц, но мой вариант не работает, как можно было бы его реализовать по-другому?

    import time 
    import requests
    import pandas as pd
    from bs4 import BeautifulSoup
    from selenium.webdriver import Chrome
    from datetime import datetime
    PAGES_COUNT = 13
    url = 'https://rozetka.com.ua/search/?page={}&producer=gazer&seller=rozetka&text=Gazer'
    url = url.replace('/?page=0', '')
    webdriver = r"C:\Users\К.Бояр (Второй)\source\repos\RozetaParcer\chromedriver.exe"


    def getPageData():
        driver = Chrome(webdriver)
    driver.implicitly_wait(10)
    driver.get("https://rozetka.com.ua/search/?producer=gazer&seller=rozetka&text=Gazer")
    total = []
    items = driver.find_elements_by_css_selector(".goods-tile.ng-star-inserted")
    cur_date = datetime.now().strftime("%d_%m_%Y")
    for item in items:
        t_name = item.find_element_by_css_selector('.goods-tile__title').text
        t_price = item.find_element_by_css_selector('.goods-tile__price-value').text
        t_nal = item.find_element_by_css_selector('.goods-tile__availability').text    
        row = cur_date, t_name, t_price, t_nal
        total.append(row)
        for pageIdx in range(0, PAGES_COUNT + 1):
            total += getPageData(pageIdx)

    driver.close()
        
    df = pd.DataFrame(total, columns=['Date','Name', 'Price', 'Nal'])
    df.to_csv(f'Rozetka_parcer_{cur_date}.csv')


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

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

Действия:

  • Разделил код на 2 части:
    1. Парсинг в функции parse
    2. Сохранение результата парсинга в функции save_goods. Кст, функция по-умолчанию использует сохранение в кодировке utf-8, если файл планируется открывать, например, в Excel, то скорее всего придется в кодировке cp1251 сохранять
  • При парсинге:
    1. Используем бесконечный цикл
    2. Загружаем страницу и вытаскиваем товары
    3. Проверяем наличие кнопки перехода на следующую страницу
    4. Если нет, то выходим из цикла, иначе сохраняем ссылку, чтобы на следующей итерации перейти по ней в 1.

У меня настроен selenium для работы с Firefox, поменяете у себя на Chrome при необходимости. Это включает в себя и Options, для Chrome используете его версию опции.

Пример:

import datetime as DT

from typing import List, Tuple, Union
from pathlib import Path

import pandas as pd

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.common.exceptions import NoSuchElementException


def parse(url: str) -> List[Tuple[str, str, str]]:
    options = Options()
    options.add_argument('--headless')

    items = []

    driver = webdriver.Firefox(options=options)
    driver.implicitly_wait(10)
    try:
        while True:
            print('Load:', url)
            driver.get(url)

            for item_el in driver.find_elements_by_css_selector(".goods-tile"):
                name = item_el.find_element_by_css_selector('.goods-tile__title').text

                # Не у всех товаров есть цена
                try:
                    price = item_el.find_element_by_css_selector('.goods-tile__price-value').text
                except NoSuchElementException:
                    price = '-'

                nal = item_el.find_element_by_css_selector('.goods-tile__availability').text

                row = name, price, nal
                print(row)
                items.append(row)

            # Если есть кнопка перехода на следующую страницу, то продолжаем цикл, иначе завершаем
            try:
                a_next_page = driver.find_element_by_css_selector('a.pagination__direction_type_forward[href]')
                url = a_next_page.get_attribute('href')

            except NoSuchElementException:
                break

    finally:
        driver.quit()

    return items


def save_goods(
        file_name: Union[str, Path],
        items: List[Tuple[str, str, str]],
        encoding='utf-8'
):
    df = pd.DataFrame(items, columns=['Name', 'Price', 'Nal'])
    df.to_csv(file_name, encoding=encoding)

Использование:

url = "https://rozetka.com.ua/search/?producer=gazer&seller=rozetka&text=Gazer"
items = parse(url)
print(f'Total goods: {len(items)}')

file_name = f'rozetka_parser_{DT.datetime.now():%Y-%m-%d}.csv'
print(f'Saved to {file_name}')
save_goods(file_name, items)

Результат (в консоли, значений много, поэтому только небольшая часть):

Load: https://rozetka.com.ua/search/?producer=gazer&seller=rozetka&text=Gazer
('Автомагнитола Gazer CM6006-100D 2-DIN', '5 699', 'Есть в наличии')
('Видеорегистратор Gazer F125 (3694553)', '2 999', 'Есть в наличии')
('Автомагнитола Gazer CM5507-100F', '3 499', 'Заканчивается')
...
Load: https://rozetka.com.ua/search/?page=13&producer=gazer&seller=rozetka&text=Gazer
...
('Автомагнитола штатная Gazer CM6510-UM для Kia Sorento (UM) 2015-2017', '21 990', 'Нет в наличии')
('Автомагнитола штатная Gazer CM6510-A40 для Toyota RAV 4 (A40) 2013-2016', '17 592', 'Нет в наличии')
('Автомагнитола штатная Gazer CM5008-XU40 для Toyota Highlander (XU40) 2008-2015', '15 899', 'Нет в наличии')
Total goods: 446
Saved to rozetka_parser_2021-10-15.csv

Результат: файл rozetka_parser_2021-10-15.csv

→ Ссылка