Перелистывание страниц с помощью парсера
Нужно написать цикл для того что бы парсер собирал данные со всех страниц, но мой вариант не работает, как можно было бы его реализовать по-другому?
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 части:
- Парсинг в функции
parse - Сохранение результата парсинга в функции
save_goods. Кст, функция по-умолчанию использует сохранение в кодировкеutf-8, если файл планируется открывать, например, в Excel, то скорее всего придется в кодировкеcp1251сохранять
- Парсинг в функции
- При парсинге:
- Используем бесконечный цикл
- Загружаем страницу и вытаскиваем товары
- Проверяем наличие кнопки перехода на следующую страницу
- Если нет, то выходим из цикла, иначе сохраняем ссылку, чтобы на следующей итерации перейти по ней в 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