如何使用Scrapy将多个页面的结果刮到一个项目中?
应考虑的页面:
- 原始页面
o
(例如,由start_requests()
给出) urls
中的所有页url
,其中urls
是通过根据parse()
擦除o
而创建的字段。
请注意,不同o
的urls
可能不会不相交。
具体示例
我有一个spider,它可以为条目'i'(即一个scrubed页面)生成以下字段:
id
prio
个urls
个
urls
是一个url列表,对于每个url(不是死的),我想从url中提取一些信息来扩展i
的字段
image_list
个head_list
最后,我希望对结果项进行筛选,以便对于每个id
,只保留具有最高prio
的项。
我所尝试的
因为我已经读到所有的抓取都应该在spider中完成(而不是在items pipeline组件中),所以我认为最好的方法是通过以下方式将抓取与后处理分离:
1.使用一个蜘蛛,它从起始页面收集所有数据,通过parse
将数据解析成i
,然后为i
的urls
中的每个URL调用response.follow(url, callback=self.parse_given_url, meta={'item':i})
parse_given_url
会将元数据提取到i
中,解析给定的url,并将image_list
和head_list
添加到i
中
1.通过项目流水线组件对所有的抓取数据进行所有的后处理(合并和过滤),以获得所有的最终项目。
我的方法的一个最小的可重复的例子:
import scrapy
class Minimal(scrapy.Spider):
name = "minimal"
def start_requests(self):
url = 'https://www.arztsuche-bw.de/index.php?suchen=1&id_fachgruppe=441&arztgruppe=facharzt&plz=761&direction=ASC'
yield scrapy.Request(url=url, method="POST", callback=self.parse)
def parse(self, response):
for office in response.css('li.row.resultrow.even') + response.css('li.row.resultrow.odd'):
full_name = office.css('dd.name dl').xpath('string(.//dt[1])').get()
contact_selectors = office.css('dd.adresse dl dd')
urls = contact_selectors.xpath('.//a[@title="Homepage aufrufen"]/@href').getall()
office_data = {
'name': full_name,
'url': urls,
}
if urls:
for url in urls:
yield response.follow(url, callback=self.parse_hp, meta={'item':office_data})
else:
yield office_data
def parse_hp(self, response):
office_data = response.meta['item']
return {
**office_data,
'hp_head': response.xpath('//h1/text()').get(),
'hp_logo_image': response.xpath('//img/@src').get(),
}
然而,由于来自不同项的urls
字段不是不相交的,所以来自response.follow_all()
调用的一些请求被丢弃,因此结果项丢失。我可以将参数dont_filter=True
添加到response.follow_all()
调用中,但是这样一个url可能会被多次抓取,这是我希望避免的。因此,我感觉我的方法不正确。
1条答案
按热度按时间oymdgrw71#
要将来自主网站的信息与从各个诊所网站上挑选的信息结合起来,您可以执行以下操作(编辑:包括
custom_settings
,以及没有网站的重定向到“google.com”,现在它将产生63个结果中的56个-需要进一步调试):您的
items.py
文件应如下所示:使用
scrapy crawl doctors -o doctors_germ.json
运行,您会得到一个json文件,如下所示: