【问题标题】:Scrapy: FormRequest from CSV, export in order or with search termScrapy:来自 CSV 的 FormRequest,按顺序或搜索词导出
【发布时间】:2017-09-03 23:53:06
【问题描述】:

我是 Python 和 Scrapy 的新手,在使用我制作的使用 FormRequest 抓取搜索结果页面上的标题的简单爬虫时遇到了一些问题。

基本上,这个想法是让一个 csv 填充搜索词并通过相同的表单运行它们,从结果页面中选择标题,然后导出到不同(或相同)的 csv。

搜索工作正常 - 输出符合预期/预期。

问题在于它以页面加载的顺序导出标题以用于scrapy,这意味着它们与原始 csv 相比是无序的,并且我无法将它们匹配回原始 csv 中的行。

这是我的代码:

from scrapy.item import Item, Field
from scrapy.http import FormRequest
from scrapy.spider import Spider

class ExampleSpider(Spider):
    name = "examplecsv"
    allowed_domains = ["examplewebsite.com"]
    start_urls = ["https://www.examplewebsite.com"]

    def parse(self, response):
        with open('addresses.csv') as fp:
            for line in fp:
                yield FormRequest.from_response(response,
                                        formdata={'examplesearchfield':line},
                                        clickdata={'id': 'clickexamplesearch'},
                                        callback=self.parse1)

    def parse1 (self, response):

        for title in response.css('title'):
            yield {

                'title':title.css('title::text').re(r'^[^|]+(?=|)')
            }

我在 StackOverflow 上进行了大量搜索,但在使用 FormRequest 方面找不到与我匹配的问题。我尝试将 CONCURRENT_REQUESTS 设置为 1 但这没有帮助。

有没有办法强制scrapy在继续之前等待每个FormRequest完成,或者在其输出中包含输入搜索词?

我的 Python 知识并不高深,所以我希望对代码进行简单的调整会有所帮助。

任何指导将不胜感激。

【问题讨论】:

    标签: python scrapy


    【解决方案1】:

    最简单的大概是在request.meta dict中加上原来的行号,解析的时候输出。

    类似这样的东西(未经测试):

    from scrapy.item import Item, Field
    from scrapy.http import FormRequest
    from scrapy.spider import Spider
    
    class ExampleSpider(Spider):
        name = "examplecsv"
        allowed_domains = ["examplewebsite.com"]
        start_urls = ["https://www.examplewebsite.com"]
    
        def parse(self, response):
            with open('addresses.csv') as fp:
                for i, line in enumerate(fp, start=1):
                    yield FormRequest.from_response(response,
                                            formdata={'examplesearchfield':line},
                                            clickdata={'id': 'clickexamplesearch'},
                                            callback=self.parse1,
                                            meta={'lineno': i})
    
        def parse1 (self, response):
    
            for title in response.css('title'):
                yield {
    
                    'title':title.css('title::text').re(r'^[^|]+(?=|)'),
                    'lineno': response.meta['lineno']
                }
    

    【讨论】:

      【解决方案2】:

      您可以将 CSV 数据添加到您的请求中,并将其包含在您的最终收益中。 这将创建一个不需要“将它们重新匹配在一起”的输出。

      from scrapy.item import Item, Field
      from scrapy.http import FormRequest
      from scrapy.spider import Spider
      
      class ExampleSpider(Spider):
          name = "examplecsv"
          allowed_domains = ["examplewebsite.com"]
          start_urls = ["https://www.examplewebsite.com"]
      
          def parse(self, response):
              with open('addresses.csv') as fp:
                  for line in fp:
                      yield FormRequest.from_response(response,
                                              formdata={'examplesearchfield':line},
                                              clickdata={'id': 'clickexamplesearch'},
                                              meta={'line' : line },
                                              callback=self.parse1)
      
          def parse1 (self, response):
      
              for title in response.css('title'):
                  yield {
                      'line' : response.meta.get('line')
                      'title':title.css('title::text').re(r'^[^|]+(?=|)')
                  }
      

      【讨论】:

        猜你喜欢
        • 2013-09-07
        • 1970-01-01
        • 2019-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多