Python. Парсинг. Как сделать парсинг всех страниц сайта?

Рейтинг: 0Ответов: 1Опубликовано: 07.05.2023
import requests
from bs4 import BeautifulSoup
import csv
import openpyxl
import pandas as pd
import xlsxwriter
import xlrd
from openpyxl import load_workbook
import numpy as np
from csv import writer
from lxml import html

headers = {
    'accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
    'user-agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 OPR/94.0.0.0 (Edition Yx 02)'

}


url = 'https://www.divan.ru/category/krovati'
response = requests.get(url)  # обработка запроса метотдом get
soup = BeautifulSoup(response.text, 'lxml')  # создаем суп
item = soup.find_all('div', {'class' : 'LlPhw'})
nami = soup.find_all('a', {'class': 'ImmXq dpmhZ b8BqN ProductName'})

pagination = soup.find('div', class_='dqBvL').find_all('a')
pages = pagination[-2].text
print('Всего страниц: ' + pages)


data = []
for page in range(1, int(pages)+1):
    response = requests.get(url, headers=headers, params={'PAGEN_1': page})
    html = response.text
    soup = BeautifulSoup(html, 'html.parser')
    blocks = soup.find('div', class_= 'Lei8X').find_all('div', class_='LlPhw')
    for block in blocks:
        title = item.find('a').get_text(strip=True)
        print(block)


for index, i in enumerate(item, start=1):
    blocks = soup.find('div', class_='dqBvL').find_all('a')
    nami = i.find('a', {'class': 'ImmXq dpmhZ b8BqN ProductName'}).text.strip()
    print(f'{index}. {nami}')

    
with xlsxwriter.Workbook('m.xlsx') as workbook:
    worksheet = workbook.add_worksheet()

    content = ["N", "Наименование"]

    worksheet.write_row(0, 0, content)

    for index, i in enumerate(item, start=1):
        nami = i.find('a', {'class': 'ImmXq dpmhZ b8BqN ProductName'}).text.strip()
        row = [index, nami]
        worksheet.write_row(index, 0, row)

Подскажите пожалуйста, как сделать парсинг всех страниц ? То, что у меня, выдает ошибку:

Traceback (most recent call last):
  File "C:\Users\Максим\PycharmProjects\pythonProject4\main.py", line 39, in <module>
    title = item.find('a').get_text(strip=True)
            ^^^^^^^^^
  File "C:\Users\Максим\.virtualenvs\pythonProject4\Lib\site-packages\bs4\element.py", line 2289, in __getattr__
    raise AttributeError(
AttributeError: ResultSet object has no attribute 'find'. You're probably treating a list of elements like a single element. Did you call find_all() when you meant to call find()?
    введите сюда код

Ответы

▲ 1

Ошибка происходит т.к. item - это не один элемент, а список элементов. Скорее всего в строке вместо item имелось ввиду block, но исправление этого не поможет действовать коду по вашей задумке т.к. в таблице будет всего 30 товаров вместо 544 как в сумме на всех страницах. Так что я думаю вы хотите получить код наподобие этого:

import xlsxwriter
from bs4 import BeautifulSoup

headers = {
    'accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
    'user-agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 '
                  'Safari/537.36 OPR/94.0.0.0 (Edition Yx 02)'

}

url = 'https://www.divan.ru/category/krovati/'

response = requests.get(url)

soup = BeautifulSoup(response.text, 'lxml')  # создаем суп

pagination = soup.find('div', class_='dqBvL').find_all('a')
pages = int(pagination[-2].text)

print(f'Всего страниц: {pages}')

# Номер текущего товара
block_no = 1

data = []

for page in range(1, pages + 1):
    page_response = requests.get(url + f'page-{page}', headers=headers)
    page_soup = BeautifulSoup(page_response.text, 'lxml')
    # Находим все блоки с товаром
    blocks = page_soup.find('div', class_='Lei8X').find_all('div', class_='LlPhw')
    # Проходимся по ним
    for block in blocks:
        # Ищем наименование
        title = block.find('a', {'class': 'ImmXq dpmhZ b8BqN ProductName'}).text.strip()
        data.append([block_no, title])
        block_no += 1

with xlsxwriter.Workbook('m.xlsx') as workbook:
    worksheet = workbook.add_worksheet()

    content = ["N", "Наименование"]

    worksheet.write_row(0, 0, content)

    for index, row in enumerate(data, start=1):
        worksheet.write_row(index, 0, row)

    worksheet.autofit()  # Подбираем размер ячеек (Необязательно, но приятно)