Слетают фильтры после перехода по элементу пагинации
Ребята, почему у меня во время перелистывания страницы первую страницу парсит как надо, потом слетают фильтры и парсит вообще что попало?
Load:
https://www.foxtrot.com.ua/uk/searchquery=Gazer&filter=_195_588&pFilter=%2C9501%3D115448&page=1
После этой страницы фильтры слетают
Load: https://www.foxtrot.com.ua/uk/search?page=2
Вот результат выполнения программы:
('Автомагнітола GAZER CM7012-J150H Toyota Prado LC150 HL', '22 392 ₴', 'КУПИТИ\nЗабрати сьогодні')
('Автомагнітола GAZER CM6510-ZD Suzuki Swift (ZD) 2004-2010', '17 592 ₴', 'КУПИТИ\nЗабрати сьогодні')
('Автомагнітола GAZER CM6510-V55', '15 992 ₴', 'КУПИТИ\nЗабрати сьогодні')
('Автомагнітола GAZER CM6509-T5 Volkswagen, Skoda, Seat, 2008-2016', '21 990 ₴', 'КУПИТИ\nЗабрати сьогодні')
('Автомагнітола GAZER CM6008-J150', '8 527 ₴', 'КУПИТИ\nЗабрати сьогодні')
('Автомагнітола GAZER CM5510-CMF для Renault Kadjar (CMF) 2015-2017', '12 719 ₴', 'КУПИТИ\nЗабрати сьогодні')
('Автомагнітола GAZER CM6509-GV Suzuki Grand Vitara (GV) 2015-2017', '8 846 ₴', 'КУПИТИ\nЗабрати сьогодні')
('Null', '-', '-')
Load: https://www.foxtrot.com.ua/uk/search?page=2
('Смартфон SAMSUNG Galaxy S20 FE 8/256GB Dual Sim ZBH Cloud Navy (SM-G780GZBHSEK)', '17 499 ₴', '19 999\n-2 500\n17 499 ₴\nот 730 ₴/мес\nКУПИТЬ')
('Телевизор HISENSE 32A5600F', '6 499 ₴', '6 999\n-500\n6 499 ₴\nот 650 ₴/мес\nКУПИТЬ')
('Стиральная машина SAMSUNG WW60J30G03WDUA', '9 999 ₴', '12 699\n-2 700\n9 999 ₴\nот 1000 ₴/мес\nКУПИТЬ')
('Пылесос ROWENTA RO4811EA', '3 199 ₴', '4 399\n-1 200\n3 199 ₴\nот 320 ₴/мес\nКУПИТЬ')
('', '', '')
Вот проблемная функция:
def parse(url: str) -> List[Tuple[str, str, str]]:
options = Options()
options.add_argument('--headless')
items = []
driver = webdriver.Firefox(options=options)
driver.implicitly_wait(5.5)
try:
while True:
print('Load:', url)
driver.get(url)
for item_el in driver.find_elements_by_css_selector(".card:last-child"):
try:
name = item_el.find_element_by_css_selector('.card__title').text
except:
name = ('Null')
# Не у всех товаров есть цена
try:
price = item_el.find_element_by_css_selector('.card-price').text
except NoSuchElementException:
price = '-'
try:nal = item_el.find_element_by_css_selector('.card__buttons').text
except NoSuchElementException:
nal = "-"
row = name, price, nal
print(row)
items.append(row)
# Если есть кнопка перехода на следующую страницу, то продолжаем цикл, иначе завершаем
try:
a_next_page = driver.find_element(By.XPATH,'//*[@id="search-page-container"]/div[3]/div/div/div[2]/div/nav/ul/li[6]/a')
url = a_next_page.get_attribute('href')
except NoSuchElementException:
break
Полный код: https://dpaste.org/rL0z
Ответы (1 шт):
Автор решения: gil9red
→ Ссылка
Пагинация сделана через проход по страницам, а номер конечной страницы определяется/обновляется на каждой итерации.
Сильно облегчает работу то, что количество страниц есть в атрибуте:

Пример:
import datetime as DT
import time
from typing import List, Tuple, Union
from pathlib import Path
# pip install pandas
import pandas as pd
# pip install selenium
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.common.exceptions import NoSuchElementException
def get_text_by_css(parent, css_selector: str, default: str) -> str:
try:
return parent.find_element_by_css_selector(css_selector).text
except:
return default
def parse(url_search: str) -> List[Tuple[str, str, str]]:
options = Options()
options.add_argument('--headless')
items = []
driver = webdriver.Firefox(options=options)
driver.implicitly_wait(5.5)
try:
page = last_page = 1
while page <= last_page:
url = url_search
if page > 1:
url = f'{url_search}&page={page}'
print(f'Load: {url}')
driver.get(url)
for item_el in driver.find_elements_by_css_selector(".card[data-url]"):
name = get_text_by_css(item_el, '.card__title', 'Null')
price = get_text_by_css(item_el, '.card-price', '-')
nal = get_text_by_css(item_el, '.card__buttons', '-')
row = name, price, nal
print(row)
items.append(row)
# Обновление номера последней страницы
try:
pages_count_el = driver.find_element_by_css_selector('*[data-pages-count]')
last_page = int(pages_count_el.get_attribute('data-pages-count'))
except NoSuchElementException:
break
page += 1
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)
if __name__ == '__main__':
url = "https://www.foxtrot.com.ua/ru/search?query=gazer&filter=_195_588"
items = parse(url)
print(f'Total goods: {len(items)}')
file_name = f'foxtrot_parser_{DT.datetime.now():%Y-%m-%d}.csv'
print(f'Saved to {file_name}')
save_goods(file_name, items)