:: Не фоксом единым
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
Я заменил код на вот такой с соблюдением отступов:
if title:
self.products.append({'Название': title.strip(), 'Цена': price.replace(' ', '')})
и получил вот такое сообщение:
ReactorNotRestartable Traceback (most recent call last)
<ipython-input-9-f96be4a3fa5a> in <cell line: 0>()
64
65 if __name__ == '__main__':
---> 66 main()
В конце выдал ещё три ячейки (cell) c диагностикой и внизу:
ReactorNotRestartable
Первая версия, которая работала и создавала xlsx тоже перестала работать и выдаёт такую же диагностику в colab.



Исправлено 1 раз(а). Последнее : glaz58, 20.04.25 20:44
Ratings: 0 negative/0 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
Я пока в colab запускаю.
Ratings: 0 negative/0 positive
Re: web data scraping
chunihin-df

Сообщений: 151
Откуда: Тюмень
Дата регистрации: 18.11.2013
Это привет от colab, надо перезапустить рантайм
Ratings: 0 negative/0 positive
Re: web data scraping
chunihin-df

Сообщений: 151
Откуда: Тюмень
Дата регистрации: 18.11.2013
для glaz58: Форум ссылки сворачивает
dimag
powershell -ExecutionPolicy ByPass -c "irm astral.sh | iex"
Там ps скрипт в общем
irm https:\\astral.sh\\uv\\install.ps1 | iex



Исправлено 1 раз(а). Последнее : chunihin-df, 20.04.25 20:56
Ratings: 0 negative/0 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
Restart session
Are you sure you want to restart the runtime? Runtime state including all local variables will be lost.
Вот это?
Ratings: 0 negative/0 positive
Re: web data scraping
chunihin-df

Сообщений: 151
Откуда: Тюмень
Дата регистрации: 18.11.2013
glaz58
Restart session
Да
Ratings: 0 negative/0 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
def parse(self, response):
try:
for item_info in response.css('.item_info'):
title = item_info.css('.item-title').xpath('./a/span/text()').get()
if title:
self.products.append({'Название': title.strip(), 'Цена': price.replace(' ', '')})
next_page = response.css('a.flex-next::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
except Exception as e:
logging.error(f"Ошибка при парсинге: {str(e)}")
В приведённой выше функции я изменил одну строку (добавил попытку сохранить цену)
self.products.append({'Название': title.strip(), 'Цена': price.replace(' ', '')})
по совету участника форума chunihin-df
Ниже строки диагностики colab
DEBUG:scrapy.core.engine:Crawled (200) <GET https://lider-vrn.ru/catalog/santekhnika/>; (referer: None)
ERROR:root:Ошибка при парсинге: name 'price' is not defined
Старая версия, которая создаёт xlsx из одного столбца, работает



Исправлено 1 раз(а). Последнее : glaz58, 21.04.25 10:38
Ratings: 0 negative/0 positive
Re: web data scraping
chunihin-df

Сообщений: 151
Откуда: Тюмень
Дата регистрации: 18.11.2013
В сообщении об ошибке указано, что переменная price должна быть определена
Вот пример
for item_info in response.css('.item_info'):
title = item_info.css('.item-title').xpath('./a/span/text()').get()
price = item_info.css('.price_value::text').get()
if title:
self.products.append({'Название': title.strip(), 'Цена': price.replace(' ', '')})
Ratings: 0 negative/0 positive
Re: web data scraping
ssa

Сообщений: 13115
Откуда: Москва
Дата регистрации: 23.03.2005
glaz58
title = item_info.css('.item-title').xpath('./a/span/text()').get()
...
В приведённой выше функции я изменил одну строку (добавил попытку сохранить цену)
self.products.append({'Название': title.strip(), 'Цена': price.replace(' ', '')})
по совету участника форума chunihin-df
Ниже строки диагностики colab
DEBUG:scrapy.core.engine:Crawled (200) <GET https://lider-vrn.ru/catalog/santekhnika/>; (referer: None)
ERROR:root:Ошибка при парсинге: name 'price' is not defined
Разумеется. С какого перепугу и откуда в title, то бишь текстовом заголовке, появится цена? Может её сначала, как и title, таки получить?
Цитата:
Старая версия, которая создаёт xlsx из одного столбца, работает
Она не пытатся сохранить то, что еще не извлекали...

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
Спасибо, Дмитрий! Всё отработало и выдало таблицу. В числовом столбце форматирование почему-то по левому краю, хотя там находится число. Для других похожих сайтов потребуется много подпиливать? В какой части программы указание на специфическую структуру сайта? Маловероятно, что я бы нашёл такую помощь на Github. Требуется значимое допиливание: добавить столбец ед.изм., где ед.изм. может быть ''шт.', 'пог.', 'кг', 'т' и т.д. Я вношу исправление в программу:
for item_info in response.css('.item_info'):
title = item_info.css('.item-title').xpath('./a/span/text()').get()
price = item_info.css('.price_value::text').get()
edizm = item_info.css('.edizm_value::text').get()
if title:
self.products.append({'Название': title.strip(), 'Цена': price.replace(' ', ''), 'Ед.изм.': edizm.replace(' ', '')})

ERROR:root:Ошибка при парсинге: 'NoneType' object has no attribute 'replace'
Это из-за того, что значение текстовое, а не числовое? Как мне извлечь в третий столбец единицу измерения?



Исправлено 4 раз(а). Последнее : glaz58, 21.04.25 18:37
Ratings: 0 negative/0 positive
Re: web data scraping
dimag

Сообщений: 484
Откуда: Одинцово
Дата регистрации: 17.12.2002
glaz58
Для других похожих сайтов потребуется много подпиливать? В какой части программы указание на специфическую структуру сайта?

Спроси DeepSeek, например. Первый вариант кода ИИ написал секунд за 10

Вот доработанный код с ценой:

import scrapy
import pandas as pd
import logging
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
class LiderVrnSpider(scrapy.Spider):
name = 'lider-vrn'
start_urls = ['https://lider-vrn.ru/catalog/santekhnika/']
def __init__(self):
super().__init__()
self.products = []
logging.info("Инициализация паука для сбора данных")
def parse(self, response):
try:
for item_info in response.css('.item_info'):
title = item_info.css('.item-title').xpath('./a/span/text()').get()
# Извлекаем цену и единицу измерения
price = item_info.css('.price_value::text').get('').strip()
price_measure = item_info.css('.price_measure::text').get('').strip().replace('/', '')
self.products.append({
'Название': title,
'Цена': float(''.join(filter(str.isdigit, price))),
'Валюта': 'руб.',
'Единица измерения': price_measure
})
next_page = response.css('a.flex-next::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
except Exception as e:
logging.error(f"Ошибка при парсинге: {str(e)}")
def closed(self, reason):
try:
df = pd.DataFrame(self.products)
if not df.empty:
# Удаляем записи, где не удалось извлечь цену
df = df.dropna(subset=['Цена'])
# Сохраняем в Excel с автоподбором ширины столбцов
with pd.ExcelWriter('lider_vrn_products.xlsx', engine='xlsxwriter') as writer:
df.to_excel(writer, index=False)
# Автоподбор ширины столбцов
worksheet = writer.sheets['Sheet1']
for i, col in enumerate(df.columns):
max_len = max(df[col].astype(str).map(len).max(), len(col)) + 2
worksheet.set_column(i, i, max_len)
logging.info(f"Успешно сохранено {len(df)} товаров в lider_vrn_products.xlsx")
else:
logging.warning("Не найдено данных для сохранения")
except Exception as e:
logging.error(f"Ошибка при сохранении в Excel: {str(e)}")
def main():
# Настройка логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Конфигурация Scrapy
settings = get_project_settings()
settings.update({
'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'LOG_LEVEL': 'INFO',
'FEED_EXPORT_ENCODING': 'utf-8',
'ROBOTSTXT_OBEY': False,
'DOWNLOAD_DELAY': 1,
'CONCURRENT_REQUESTS': 2,
})
process = CrawlerProcess(settings)
process.crawl(LiderVrnSpider)
process.start()
if __name__ == '__main__':
main()


------------------
Never judge a book by its cover.




Исправлено 2 раз(а). Последнее : dimag, 21.04.25 18:27
Ratings: 0 negative/1 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
К сожалению, ничего не сохранил в xlsx, хотя ошибок при выполнении не было. В коде есть строки для сохранения в xlsx, но почему-то не сохраняет.
No module named 'xlsxwriter'. В прежних версиях тоже не было такого модуля, но в xlsx сохранялось.
# Сохраняем в Excel с автоподбором ширины столбцов
with pd.ExcelWriter('lider_vrn_products.xlsx', engine='xlsxwriter') as writer:
df.to_excel(writer, index=False)
ERROR:root:Ошибка при сохранении в Excel: No module named 'xlsxwriter'
А так видно, что скрэйпит нормально



Исправлено 5 раз(а). Последнее : glaz58, 21.04.25 19:12
Ratings: 0 negative/0 positive
Re: web data scraping
dimag

Сообщений: 484
Откуда: Одинцово
Дата регистрации: 17.12.2002
Не сохраняет потому что нет xlsxwriter.

В powershell перейди в каталог с проектом и добавь
uv add xlsxwriter
или через pip

------------------
Never judge a book by its cover.
Ratings: 0 negative/0 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
dimag
xlsxwriter
pip xlsxwriter
вот так?
Ratings: 0 negative/0 positive
Re: web data scraping
chunihin-df

Сообщений: 151
Откуда: Тюмень
Дата регистрации: 18.11.2013
glaz58
pip xlsxwriter

pip install xlsxwriter
Ratings: 0 negative/0 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
Спасибо, обязательно испытаю
Ratings: 0 negative/0 positive
Re: web data scraping
chunihin-df

Сообщений: 151
Откуда: Тюмень
Дата регистрации: 18.11.2013
glaz58
Для других похожих сайтов потребуется много подпиливать? В какой части программы указание на специфическую структуру сайта? Маловероятно, что я бы нашёл такую помощь на Github. Требуется значимое допиливание: добавить столбец ед.изм., где ед.изм. может быть ''шт.', 'пог.', 'кг', 'т' и т.д.
[attachment 37130 plumber.gif]
Ratings: 0 negative/1 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
Это уж слишком. Там написано Р/шт или Р/к-т или Р/пог. и т.д. Именно это и надо сохранить. Только символ рубля не хочет сюда вставлять.



Исправлено 1 раз(а). Последнее : glaz58, 22.04.25 11:53
Ratings: 0 negative/0 positive
Re: web data scraping
glaz58
Автор

Сообщений: 885
Откуда: Воронеж
Дата регистрации: 09.02.2008
В программе применяется pd.ExcelWriter(.......
При попытке запустить
pip install ExcelWriter
выдаёт ошибку
ERROR: Could not find a version that satisfies the requirement ExcelWriter (from versions: none)
ERROR: No matching distribution found for ExcelWriter
Ratings: 0 negative/0 positive
Re: web data scraping
dimag

Сообщений: 484
Откуда: Одинцово
Дата регистрации: 17.12.2002
glaz58
В программе применяется pd.ExcelWriter(.......
При попытке запустить
pip install ExcelWriter
выдаёт ошибку
ERROR: Could not find a version that satisfies the requirement ExcelWriter (from versions: none)
ERROR: No matching distribution found for ExcelWriter


pd.ExcelWriter это пакет pandas

Тебе нужно:
pip install xlsxwriter



Я же четко писал об этом выше:
Не сохраняет потому что нет xlsxwriter.
dimag

В powershell перейди в каталог с проектом и добавь
uv add xlsxwriter
или через pip

# Анализ кода парсера для сайта lider-vrn.ru

## Описание функционала

Scrapy-паук для сбора данных о сантехнических товарах с сайта `lider-vrn.ru`.

### Основные компоненты:

1. **Класс паука `LiderVrnSpider`**
- Наследуется от `scrapy.Spider`
- Имя паука: `'lider-vrn'`
- Стартовая URL: `'https://lider-vrn.ru/catalog/santekhnika/'`

2. **Методы:**
- `__init__`: Инициализация списка для хранения товаров
- `parse`: Основной метод парсинга страниц
- `closed`: Финализация и сохранение результатов

## Процесс парсинга

1. **Извлечение данных:**
for item_info in response.css('.item_info'):
title = item_info.css('.item-title').xpath('./a/span/text()').get()
price = item_info.css('.price_value::text').get('').strip()
price_measure = item_info.css('.price_measure::text').get('').strip().replace('/', '')

2.Структура данных:

{
'Название': title,
'Цена': float(''.join(filter(str.isdigit, price))),
'Валюта': 'руб.',
'Единица измерения': price_measure
}

3.Пагинация:

next_page = response.css('a.flex-next::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)

Сохранение результатов
Обработка данных:

Конвертация в DataFrame

Удаление записей с пустыми ценами

Экспорт в Excel:

with pd.ExcelWriter('lider_vrn_products.xlsx', engine='xlsxwriter') as writer:
df.to_excel(writer, index=False)
# Автоподбор ширины столбцов

Настройки проекта
settings = {
'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0...)',
'LOG_LEVEL': 'INFO',
'FEED_EXPORT_ENCODING': 'utf-8',
'ROBOTSTXT_OBEY': False,
'DOWNLOAD_DELAY': 1,
'CONCURRENT_REQUESTS': 2
}
Инструкция по установке и запуску
1. Установка зависимостей
bash
pip install scrapy pandas xlsxwriter
2. Варианты запуска
Способ 1 (как standalone-скрипт):

bash
python spider_script.py
Способ 2 (через Scrapy CLI):

bash
scrapy crawl lider-vrn

Возможные проблемы и решения
Ошибки зависимостей:

Проверить версии пакетов

Создать requirements.txt:

scrapy>=2.5.0
pandas>=1.3.0
xlsxwriter>=3.0.0

Блокировка запросов:
Увеличить DOWNLOAD_DELAY

Использовать прокси

Обновить USER_AGENT

Изменения структуры сайта:

Адаптировать CSS-селекторы


# Новые селекторы при изменении верстки
response.css('.new-item-class')
Логирование
Настроено логирование с уровнем INFO:

logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)


------------------
Never judge a book by its cover.




Исправлено 4 раз(а). Последнее : dimag, 24.04.25 16:09
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 7 alex;  (Гостей: 6)

© 2000-2025 Fox Club 
Яндекс.Метрика