如何通过两个函数传递url - 回调

时间:2017-06-13 17:43:55

标签: python callback scrapy yield

设置向上

我正在用scrapy抓住住房广告:根据住房广告,我抓住了几个住房特征。

刮擦外壳特性很好。

<小时/> 的问题

除了房屋特征,我想每个广告拍一张图片。

我有以下代码:

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命令,这些命令不起作用。也就是说,我得到的是特征,但不是图像。

我可以对第一个进行评论,以便获得图像。

如何解决这个问题,以便我同时解决这个问题?提前致谢。

2 个答案:

答案 0 :(得分:0)

将它们放在一起。

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 :(得分:0)

我有两个主要建议:

第1名

我强烈建议您重新编写代码,以便同时实现所有信息的分配。

,而不是拥有两个单独的parse_X函数......只需要一个获取信息并返回单个项目。

第2名

实现一个Spider Middleware,它可以进行类似于以下管道的合并/拆分。一个简单的示例中间件是https://github.com/scrapy/scrapy/blob/ebef6d7c6dd8922210db8a4a44f48fe27ee0cd16/scrapy/spidermiddlewares/urllength.py。您只需合并项目并在它们进入itempipelines之前跟踪它们。

警告不要做以下事项。我正在推荐这个,而且该代码可能会工作......但是有一些潜在的隐藏问题。

我在这里完成我正在研究的内容 - 建议不要在这里: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)