Set-up
我正在抓取带有刮擦的住房广告:每个住房广告我都会抓取几个住房特征。
刮擦外壳特性工作正常。
问题
除了外壳特性外,我还想为每个广告抓取一张图片。
我有以下代码:
class ApartmentSpider(scrapy.Spider):
name = 'apartments'
start_urls = [
'http://www.jaap.nl/huurhuizen/noord+holland/groot-amsterdam/amsterdam'
]
def parse(self, response):
for href in response.xpath(
'//*[@id]/a',
).css("a.property-inner::attr(href)").extract():
yield scrapy.Request(response.urljoin(href),
callback=self.parse_ad) # parse_ad() scrapes housing characteristics
yield scrapy.Request(response.urljoin(href),
callback=self.parse_AdImage) # parse_AdImage() obtains one image per ad
所以,我有两个yield
命令,它们不起作用。也就是说,我得到了特征,但没有图像。
我可以评论第一个,这样我就可以得到图像。
我如何解决这个问题,以便我同时得到两者?提前谢谢。
只要把它们放在一起。
yield (scrapy.Request(response.urljoin(href), callback=self.parse_ad), scrapy.Request(response.urljoin(href), callback=self.parse_AdImage))
在接收端,将两者作为单独的值抓取
characteristics, image = ApartmentSpider.parse(response)
我有两个主要建议:
数字 1
我强烈建议重新编写您的代码,以同时实际提供所有信息。 而不是有两个独立的parse_X功能...只需有一个获取信息并返回单个项目。
数字 2
实现一个蜘蛛中间件,它进行合并/拆分,类似于我在下面为管道提供的。 一个简单的示例中间件是 https://github.com/scrapy/scrapy/blob/ebef6d7c6dd8922210db8a4a44f48fe27ee0cd16/scrapy/spidermiddlewares/urllength.py。 您只需合并项目并在它们进入项目管道之前在此处跟踪它们。
警告 不要执行以下操作。 我打算建议这个,代码可能会起作用......但有一些潜在的隐藏问题。
它在这里是为了完成我正在研究的内容 - 建议不要在这里:https://github.com/scrapy/scrapy/issues/1915
在 scrapy 中使用项目处理管道。 它们对于积累数据非常有用。 有一个项目连接器管道,其目的是等待两个单独的部分数据项,并将它们连接成一个项目,并在广告 ID(或其他一些唯一数据片段)上键入它们。
在粗略的不可运行的伪代码中:
class HousingItemPipeline(object):
def __init__():
self.assembledItems = dict()
def process_item(self, item, spider):
if type(item, PartialAdHousingItem):
self.assembledItems[unique_id] = AssembledHousingItem()
self.assembledItems[unique_id]['field_of_interst'] = ...
...assemble more data
raise DropItem("Assembled it's data")
if type(item, PartialAdImageHousingItem):
self.assembledItems[unique_id]['field_of_interst'] = ...
...assemble more data
raise DropItem("Assembled it's data")
if Fully Assembled:
return self.assembledItems.pop(unique_id)