【问题标题】:How to pass url through two functions - Callback如何通过两个函数传递 url - 回调
【发布时间】:2017-11-15 15:05:55
【问题描述】:

设置

我正在用 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 命令,但不起作用。也就是说,我得到了特征,但没有得到图像。

我可以评论第一个,这样我就可以得到图像。

我如何解决这个问题,以便我得到两者?提前致谢。

【问题讨论】:

  • 两次屈服的意图是什么?似乎最明显的解决方案是同时发送两者。
  • 我想要特征和图像。所以两次产量,因为我不知道如何命令它,以便一次产量给我想要的结果。显然,这种“直观”的解决方案失败了。
  • 为什么不只产生两个结果的元组?
  • 你能告诉我什么是元组吗?

标签: python callback scrapy yield


【解决方案1】:

我有两个主要建议:

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)

【讨论】:

    【解决方案2】:

    只需将它们同时屈服即可。

    yield (scrapy.Request(response.urljoin(href), callback=self.parse_ad), scrapy.Request(response.urljoin(href), callback=self.parse_AdImage))
    

    在接收端,将两者作为单独的值获取

    characteristics, image = ApartmentSpider.parse(response)
    

    【讨论】:

    • 谢谢亚历克斯,不过我不确定你所说的“在接收端”是什么意思?
    • 无论您在哪里捕获从收益返回的值。您正在将返回类型更改为元组。为保持您当前的行为,请将您今天用于捕获此信息的两个变量放在同一行,等号左侧,用逗号分隔。
    猜你喜欢
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    相关资源
    最近更新 更多