Scrapy:CSV格式的FormRequest,按顺序导出或使用搜索字词

时间:2017-09-03 23:53:07

标签: python scrapy

我是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知识不高级,所以我希望对代码有一个简单的调整可以提供帮助。

非常感谢任何指导。

2 个答案:

答案 0 :(得分:0)

您可以将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'^[^|]+(?=|)')
            }

答案 1 :(得分:0)

最简单的可能是在request.meta dict中添加原始行号并在解析时输出它。

像这样(未经测试):

{{1}}