【问题标题】:How to return to the calling parse function while using yield in scrapy?在scrapy中使用yield时如何返回调用解析函数?
【发布时间】:2014-09-14 18:22:59
【问题描述】:

这是我想要实现的目标:

class Hello(Spider):
    #some stuff
    def parse(self, response):
        #get a list of url of cities using pickle and store in a list
        #Now for each city url I have to get list of monuments (using selenium) which is achieved by the below loops
        for c in cities:
            #get the list of monuments using selenium and iterate through each monument url contained in the division
            divs = sel.xpath('some xpath/div')
            for div in divs:
               monument_url=''.join(div.xpath('some xpath'))
               #For each monument url get the response and scrape the information
               yield Request(monument_url, self.parse_monument)
    def parse_monument(self, response):
        #scrape some information and return to the loop(i.e. return to "for div in divs:") 

现在发生的事情是: 1.在yield语句执行之前,我得到了全市所有古迹的列表。
2. 每当执行 yield 语句时,它会转到 parse_monument 函数并且不会返回循环,只会抓取第一个城市中存在的纪念碑列表。

有没有办法做到这一点?有什么方法可以获取 request 方法传递给 parse_monument 的响应对象,而无需转到 parse_monument 方法,以便我可以使用选择器从响应中选择我需要的元素?

谢谢你!!

【问题讨论】:

  • yieldparse_monument 之前添加一些print,看看它是如何工作的。
  • 和我之前提到的一样。在 parse_monument 中产生第一个和第二个之前。

标签: python scrapy yield


【解决方案1】:

我认为您不能像以前那样回调函数。这是一个重构:

class HelloSpider(scrapy.Spider):
    name = "hello"
    allowed_domains = ["hello.com"]
    start_urls = (
        'http://hello.com/cities'
    )

    def parse(self, response):
        cities = ['London','Paris','New-York','Shanghai']
        for city in cities:
            xpath_exp= 'some xpath[city="' + city + '"]/div/some xpath'
            for monument_url in response.xpath(xpath_exp).extract():
                yield Request(monument_url, callback=self.parse_monument)

    def parse_monument(self,response):
        pass

【讨论】:

    【解决方案2】:

    Request 是一个对象,而不是一个方法。 Scrapy 将处理产生的 Request 对象并异步执行回调。您可以将 Request 视为线程对象。

    解决方案是通过相反的操作,将您需要的数据从 parse 方法传递给 Request,这样您就可以在 parse_monument 中处理它们。

    class Hello(Spider):
    
        def parse(self, response):
            for c in cities:
                divs = sel.xpath('some xpath/div')
                for div in divs:
                   monument_url=''.join(div.xpath('some xpath'))
    
                   data = ...   # set the data that you need from this loop
    
                   # pass the data into request's meta
                   yield Request(monument_url, self.parse_monument, meta={'data': data})
    
        def parse_monument(self, response):
            # retrieve the data from response's meta
            data = response.meta.get('data')
            ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      • 1970-01-01
      • 2016-09-07
      • 2023-03-25
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多