Очень простой скрипт для сбора товаров с интернет-магазина электроники Eldorado. По всем вопросам связанным с ошибками, неработоспособностью кода пишите в наше сообщество ВК
В данном парсере собраны и сохранены в Excel файл:
— название;
— артикул;
— цена;
— комментарии;
— ссылка.
1. Импорт используемых библиотек
from random import randint
import time
import requests
from bs4 import BeautifulSoup
import pandas as pd
from pandas import ExcelWriter
2. Получение html страницы
Функция get_html. Получаем код страницы и статус ответа на наш запрос
def get_html(url, params=None):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Firefox/89.0',
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br'}
response = requests.get(url, headers=headers, params=params)
html = response.text
print('Статус код: ', response.status_code)
return html
3. Определяем количество страниц выдачи
Функция get_pages_count ищем на странице общее количество найденного товара и делит это число на 36, где 36 это количество позиций на странице и выводим принт
def get_pages_count(html):
soup = BeautifulSoup(html, 'html.parser')
try:
goods_count = int(soup.find('span', {"data-pc": "offers_cnt"}).text.replace(' ', ''))
print(f'Количество найденных позиций: {goods_count}')
pages = goods_count//36 + 1
except:
pages = 1
print('Количество страниц: ', pages)
return pages
4. Собираем контент
Функция get_content. Со страницы будем брать название позиции, цену, рейтинг, количество отзывов, ссылку на товар. Цену и рейтинг вынес за словарь, включил в блок try-except, так как цена может быть не указана, например «скоро в продаже», а рейтинга может не быть, так как товар новый.
def get_content(html):
soup = BeautifulSoup(html, 'html.parser')
blocks = soup.find_all('li', {'data-dy': 'product'})
data = []
for block in blocks:
# столкнулся с позицией "скоро в продаже" ловим исключение
try:
price = block.find('span',{'data-pc': 'offer_price'}).text.replace(' ','').split('\xa0')[-2]
except:
price = 0
try:
rating = block.find('span', class_='ms').text
except:
rating = '0'
data.append({
'title': block.find('a', {'data-dy': "title"}).get_text(),
'article': block.find('span', {"data-dy": "article"}).text.split(' ')[-1],
'price': int(price),
'rating': rating,
'review': int(block.find('a', {'data-dy': 'review'}).text.split()[0]),
'link': 'https://www.eldorado.ru' + block.find('a', {'data-dy': "title"}).get('href')
})
return data
5. Сохраняем собранные данные
Функция save_data. Сохраняем через библиотеку pandas, через него же почистим от дубликатов, не знаю почему они есть, можете свои предложения написать в личку.
def save_data(data, file_name):
df = pd.DataFrame(data)
print(f'До удаления дубликатов: {len(df)} записей')
data_clear = df.drop_duplicates('article')
print(f'После удаления дубликатов: {len(data_clear)} записей')
writer = ExcelWriter(f'{file_name}.xlsx')
data_clear.to_excel(writer, f'{file_name[0:20]}')
writer.save()
print(f'Данные сохранены в "{file_name}.xlsx" файл')
6. Основная функция.
Функция parser(url). file_name это заголовок страницы, которую парсим.
Обязательно! Выставляем задержку между страницами, иначе, статус код будет 403 (доступ к данным запрещен!)
Я поставил задержку от 4 до 8 секунд, краш-тест до 57 страниц проходил неоднократно.
def parser(url):
html = get_html(url)
soup = BeautifulSoup(html, 'html.parser')
file_name = soup.h1.text
print(f'Выбранный раздел: {file_name}')
pages = get_pages_count(html)
data = []
for page in range(1, pages + 1):
#for page in range(14, 15):
html = get_html(url, params={"page": page})
data.extend(get_content(html))
print(f'Парсим страницу {page} из {pages}...Собрано {len(data)} позиций.')
time.sleep(randint(4, 8))
print('Найдено', len(data), 'позиций')
save_data(data, file_name)
7. Ход выполнения и результаты
if __name__ == "__main__":
parser('https://www.eldorado.ru/c/vse-igry/f/dlya-sony-playstation-5/')
Запускаем код:
Смотрим полученный результат:
Спасибо, что прочли до конца, жду от вас обратной связи, пишите что нужно рассмотреть, что подробнее объяснить, рассказать, показать. Все ответы, любую помощь можно получить у нас в ВК