Я использую Scrapy для сканирования страниц и извлечения данных в файл JSON, но столкнулся с проблемами согласованности данных. В частности, в некоторых полях сохраняются или дублируются данные из предыдущих ответов, что приводит к неправильным значениям полей в выходных данных.
Проблема
Выходной файл JSON содержит правильное количество элементов, соответствующее количеству URL-адресов в файле .txt, причем все URL-адреса уникальны. Однако некоторые поля в выводе JSON неверны и выглядят так, как будто данные из одного запроса сохраняются в другом элементе.
Я это проверил:
Для каждого ответа создается новый экземпляр ItemLoader.
Я использовал операторы if-else, чтобы добавить сообщение «НЕТ ДАННЫХ НЕ НАЙДЕНО», если данные не найдены. по указанному XPath.
Вот пример двух последовательных строк с разными URL-адресами, содержащими одинаковые данные:
Строка 20:
Объект контрато: Проект Ejecución «Abastecimiento Caseríos [...]»
< li>База предполагаемой суммы: 247 576,09 евро
URL: Ссылка на место заключения контракта
Line 21:
Объект контрато: проект Ejecución «Abastecimiento Caseríos [...]»
Предполагаемая база: 247 576,09 евро.
URL: Ссылка на место контракта по государству
Разумным подходом было бы используйте Spider вместо CrawlSpider. Однако я намерен усложнить код, как только эта первоначальная версия будет решена.
Код
Краткая информация о базовой структуре
Импорт и определения:
Импортировать ключевые модули Scrapy (элемент, поле , CrawlSpider, Rule, ItemLoader и LinkExtractor).
Класс элемента (Claselicitacion):
Определяет поля: objeto_contrato, presupuesto_base и url.
Класс Spider (LicitacionCrawlSpider):
Наследует от CrawlSpider .
Считывает URL-адреса из текстового файла (1_DeepLinks.txt) для инициализации start_urls.
Определяет правила для извлечения определенных ссылок и назначения их parse_item обратный вызов.
Метод обратного вызова (parse_item):
Создает новый экземпляр ItemLoader для каждого ответа.
Извлекает данные для каждого поля с помощью XPath.
from scrapy.item import Item, Field
from scrapy.spiders import CrawlSpider, Rule
from scrapy.loader import ItemLoader
from scrapy.linkextractors import LinkExtractor
class Claselicitacion(Item):
objeto_contrato = Field()
presupuesto_base = Field()
url = Field()
class LicitacionCrawlSpider(CrawlSpider):
name = 'licitacion_crawl'
custom_settings = {
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
'USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
'FEED_EXPORT_ENCODING': 'utf-8',
'FEEDS': {
'2_ProjectFinder.json': {
'format': 'json',
'encoding': 'utf-8',
},
}
}
with open('1_DeepLinks.txt', 'r') as file:
start_urls = [line.strip() for line in file if line.strip()]
rules = (
Rule(
LinkExtractor(allow=r'deeplink%3Adetalle_licitacion'),
callback='parse_item',
follow=False,
),
)
def parse_item(self, response):
item = ItemLoader(item=Claselicitacion(), response=response)
if response.xpath('//li[@id="fila4_columna2"]'):
item.add_xpath('objeto_contrato', '//li[@id="fila4_columna2"]//span[@class="outputText"]/text()')
else:
item.add_value('objeto_contrato', 'NO DATA FOUND')
if response.xpath('//li[@id="fila5_columna2"]'):
item.add_xpath('presupuesto_base', '//li[@id="fila5_columna2"]//span[@class="outputText"]/text()')
else:
item.add_value('presupuesto_base', 'NO DATA FOUND')
item.add_value('url', response.url)
yield item.load_item()
Вопросы
Сохраняет ли ItemLoader значения из предыдущих запросов? Как могу ли я обеспечить полное разделение данных каждого ответа?
Правильно ли я использую ItemLoader? Есть ли лучший способ справиться с этой настройкой? li> Может ли асинхронная обработка Scrapy вызвать путаницу данных? Как я могу обеспечить независимую обработку каждого запроса?
Является ли item.add_xpath + Give item.load_item() надежным подходом? Поскольку поля URL всегда корректны, могут ли возникнуть проблемы с использованием add_xpath?
Что я пробовал
Добавление условий if-else для установки " НЕТ ДАННЫХ НАЙДЕНО» в качестве заполнителя, когда данные не найдены.
Гарантируется, что экземпляр ItemLoader создается заново для каждого ответа.
Подтверждение что URL-адреса в моем исходном файле верны.
Ожидаемое поведение
Каждый элемент выходных данных должен быть независимым и содержать только данные, относящиеся к соответствующему URL-адресу. Если данные поля недоступны, в нем должно быть явно указано «ДАННЫЕ НЕ НАЙДЕНЫ».
Любые идеи или предложения по улучшению использования моего ItemLoader или изоляции состояний запроса в Scrapy будут быть очень полезным. Заранее спасибо!
Я использую Scrapy для сканирования страниц и извлечения данных в файл JSON, но столкнулся с проблемами согласованности данных. В частности, в некоторых полях сохраняются или дублируются данные из предыдущих ответов, что приводит к неправильным значениям полей в выходных данных. Проблема Выходной файл JSON содержит правильное количество элементов, соответствующее количеству URL-адресов в файле .txt, причем все URL-адреса уникальны. Однако некоторые поля в выводе JSON неверны и выглядят так, как будто данные из одного запроса сохраняются в другом элементе. Я это проверил: [list] [*]Для каждого ответа создается новый экземпляр ItemLoader. [*]Я использовал операторы if-else, чтобы добавить сообщение «НЕТ ДАННЫХ НЕ НАЙДЕНО», если данные не найдены. по указанному XPath. [/list] Вот пример двух последовательных строк с разными URL-адресами, содержащими одинаковые данные:
[b]Строка 20:[/b] [list] [*]Объект контрато: Проект Ejecución «Abastecimiento Caseríos [...]» < li>База предполагаемой суммы: 247 576,09 евро [*]URL: Ссылка на место заключения контракта [/list] [b]Line 21:[/b] [list] [*]Объект контрато: проект Ejecución «Abastecimiento Caseríos [...]» [*] Предполагаемая база: 247 576,09 евро. [*]URL: Ссылка на место контракта по государству [/list] Разумным подходом было бы используйте Spider вместо CrawlSpider. Однако я намерен усложнить код, как только эта первоначальная версия будет решена. Код [h4]Краткая информация о базовой структуре[/h4] [list] [*]Импорт и определения: [/list] [list] [*]Импортировать ключевые модули Scrapy (элемент, поле , CrawlSpider, Rule, ItemLoader и LinkExtractor). [/list] [list] [*]Класс элемента (Claselicitacion): [/list] [list] Определяет поля: objeto_contrato, presupuesto_base и url. [/list] [list] [*]Класс Spider (LicitacionCrawlSpider): [/list] [list] [*]Наследует от CrawlSpider . [*]Считывает URL-адреса из текстового файла (1_DeepLinks.txt) для инициализации start_urls. [*]Определяет правила для извлечения определенных ссылок и назначения их parse_item обратный вызов. [/list] [list] [*]Метод обратного вызова (parse_item):
[list] [*]Создает новый экземпляр ItemLoader для каждого ответа. [*]Извлекает данные для каждого поля с помощью XPath. [*]Добавляет URL-адрес ответа. [*]Получает загруженный элемент (item.load_item()). [*]Вот основная структура моего кода: [/list] [h4]Код[/h4] [code]from scrapy.item import Item, Field from scrapy.spiders import CrawlSpider, Rule from scrapy.loader import ItemLoader from scrapy.linkextractors import LinkExtractor
if response.xpath('//li[@id="fila4_columna2"]'): item.add_xpath('objeto_contrato', '//li[@id="fila4_columna2"]//span[@class="outputText"]/text()') else: item.add_value('objeto_contrato', 'NO DATA FOUND')
if response.xpath('//li[@id="fila5_columna2"]'): item.add_xpath('presupuesto_base', '//li[@id="fila5_columna2"]//span[@class="outputText"]/text()') else: item.add_value('presupuesto_base', 'NO DATA FOUND')
item.add_value('url', response.url)
yield item.load_item() [/code] Вопросы
[*][b]Сохраняет ли ItemLoader значения из предыдущих запросов?[/b] Как могу ли я обеспечить полное разделение данных каждого ответа? [*][b]Правильно ли я использую ItemLoader?[/b] Есть ли лучший способ справиться с этой настройкой? li> [b]Может ли асинхронная обработка Scrapy вызвать путаницу данных?[/b] Как я могу обеспечить независимую обработку каждого запроса? [*][b]Является ли item.add_xpath + Give item.load_item() надежным подходом?[/b] Поскольку поля URL всегда корректны, могут ли возникнуть проблемы с использованием add_xpath? [/list] Что я пробовал [list] [*]Добавление условий if-else для установки " НЕТ ДАННЫХ НАЙДЕНО» в качестве заполнителя, когда данные не найдены. [*]Гарантируется, что экземпляр ItemLoader создается заново для каждого ответа. [*]Подтверждение что URL-адреса в моем исходном файле верны. [/list] Ожидаемое поведение Каждый элемент выходных данных должен быть независимым и содержать только данные, относящиеся к соответствующему URL-адресу. Если данные поля недоступны, в нем должно быть явно указано «ДАННЫЕ НЕ НАЙДЕНЫ». Любые идеи или предложения по улучшению использования моего ItemLoader или изоляции состояний запроса в Scrapy будут быть очень полезным. Заранее спасибо!