【问题标题】:Scrapy yield a Request, parse in the callback, but use the info in the original functionScrapy 产生一个请求,在回调中解析,但使用原始函数中的信息
【发布时间】:2017-07-19 20:47:12
【问题描述】:

所以我正在尝试在scrapy中测试一些网页,我的想法是向满足条件的URLS产生一个请求,计算页面上某些项目的数量,然后在原始条件内返回True/False取决于...

这里有一些代码来说明我的意思:

def filter_categories:
    if condition:
        test = yield Request(url=link, callback = self.test_page, dont_filter=True)
        return (test, None)

def test_page(self, link):
    ... parse the response...
    return True/False depending

我尝试过在请求中传递一个项目,但无论在调用 test_page 之前触发了什么返回行...

所以我想我的问题变成了有没有办法以同步的方式将数据传递回 filter_categories 方法,以便我可以使用 test_page 的结果来返回我的测试是否满足?

也欢迎任何其他想法。

【问题讨论】:

    标签: python callback scrapy scrapy-spider


    【解决方案1】:

    看看inline_requests 包,它应该可以让你实现这一点。

    其他解决方案是不坚持从原始方法返回结果(在您的情况下为filter_categories),而是使用request chaining 和请求的meta 属性并返回链中最后一个解析方法的结果(test_page 在你的情况下)。

    【讨论】:

    • 快速跟进,我不确定您如何使用响应变量?文档/示例毫无价值
    • 因为我通过的响应最终没有
    【解决方案2】:

    如果我的理解正确:您想将yield scrapy.Request 发送到具有True 条件的 URL。我对吗?这里有一些例子:

    def parse(self, response):
        if self.test_page(response):
            item = Item()
            item['url'] = 'xpath or css'
            yield item
        if condition:
            yield Request(url=new_link, callback = self.parse, dont_filter=True)
    
    
    def test_page(self, link):
        ... parse the response...
        return True/False depending
    

    如果您提供更多信息,我会尝试提供更多帮助。

    这是我的代码的一部分

     def parse(self, response):
            if 'tag' in response.url:
                return self.parse_tag(response)
            if 'company' in response.url:
                return self.parse_company(response)
    
        def parse_tag(self, response):
            try:
                news_list = response.xpath("..//div[contains(@class, 'block block-thumb ')]")
                company = response.meta['company']
                for i in news_list:
                    item = Item()
                    item['date'] = i.xpath("./div/div/time/@datetime").extract_first()
                    item['title'] = i.xpath("./div/h2/a/text()").extract_first()
                    item['description'] = i.xpath("./div/p//text()").extract_first()
                    item['url'] = i.xpath("./div/h2/a/@href").extract_first()
    
                    item.update(self.get_common_items(company))
    
                    item['post_id'] = response.meta['post_id']
    
                    if item['title']:
                        yield scrapy.Request(item['url'], callback=self.parse_tags, meta={'item': item})
    
                has_next = response.xpath("//div[contains(@class, 'river-nav')]//li[contains(@class, 'next')]/a/@href").extract_first()
                if has_next:
                    next_url = 'https://example.com' + has_next + '/'
                    yield scrapy.Request(next_url, callback=self.parse_tag,
                                         meta=response.meta)
    
    def parse_tags(self, response):
        item = response.meta['item']
        item['tags'] = response.xpath(".//div[@class='accordion recirc-accordion']//ul//li[not(contains(@class, 'active'))]//a/text()").extract()
    
        yield item
    

    【讨论】:

    • 更多这样我需要从scrapy请求的回调中接收信息......换句话说。在我在解析中产生一个请求后,我需要在回调中解析该页面,并且根据其中的内容,我最好将真/假或一些变量返回到产生请求的“解析”方法。这将那么请允许我按要求进行。所以,换句话说,我需要产生一个请求,立即解析回调中的信息,然后在产生请求后在下一行使用该信息
    • 据我所知 - 这是不可能的。你不能从回调中返回任何值到parse 函数,只能前进。
    • 但你可以在函数test_page中制作yield
    • 我在上面添加了我的蜘蛛的一部分
    • 我不是试图返回一个值来解析,我试图从回调中返回一个值到请求产生的方法。换句话说,使请求立即执行,请求下面的代码等待回调完成,回调将一些 True/False 传递回产生请求的方法
    【解决方案3】:

    你可以使用:

    response.meta
    response.body
    

    yield from函数

    重构你的蜘蛛

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-30
      • 2020-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      相关资源
      最近更新 更多