Scrapy 暗坑之 start_requests

2018-03-01 10:32:28 +08:00
 lxy

众所周知,Scrapy 默认会过滤重复的 URL,不会重复抓取相同的 URL,除非显式指定。

于是随便写了一个爬图片地址的小虫,然而不知道为什么总会爬两次 baidu 首页,你能看出错在哪里吗?

class ImageSpider(scrapy.Spider):
    name = "images"
    allowed_domains = ["www.baidu.com"]
    start_urls = ['https://www.baidu.com/']

    def parse(self, response):
        images = response.xpath('//img/@src').extract()
        for image in images:
            image_item = ImageItem()
            image_item['img_url'] = response.urljoin(image.strip())
            yield image_item

        urls = response.xpath('//a/@href').extract()
        for url in urls:
            next_url = response.urljoin(url.strip())
            yield Request(next_url)

我想了半天都不明白为什么,以为是过滤器的问题,查了半天资料仍没解决。 后来偶然看了 Spider 源码,才发现坑爹之处。

原来源码的 start_requests 是这样写的(已忽略无关代码)

def start_requests(self):
    for url in self.start_urls:
        yield Request(url, dont_filter=True)

也就是说,因显式指定了 dont_filter=True,start_urls 中的 URL 在首次请求时不会加入过滤列表中,这样相同的 URL 第二次请求时由于不存在于过滤列表中,导致了二次抓取。

我实在不明白为什么会有这种矛盾,既然默认过滤重复 URL,那么在源码各个地方都应贯彻这个原则。

如果只是这样就算了,然而在官方教程中也埋了这样的坑: https://doc.scrapy.org/en/latest/intro/tutorial.html

在 Our first Spider 这一节中,是这样写 start_requests 的

def start_requests(self):
    urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]
    for url in urls:
        yield scrapy.Request(url=url, callback=self.parse)

然后在 A shortcut to the start_requests method 一节中表示可以把 urls 提取到 start_urls 然后直接 use the default implementation of start_requests()。让人误以为 start_requests 默认实现也没有设置 dont_filter=True。简直就是把全世界所有新手都坑了一遍……

9160 次点击
所在节点    Python
6 条回复
zachguo
2018-03-01 11:07:58 +08:00
scrapy 的源码质量。。。
你可以 PR 和维护者讨论。
不过我记得自己之前 PR 体验不好,维护者让我改代码去兼容一个几年前的依赖版本,原因是他们的 for profit 产品没升级依赖。。
swirling
2018-03-01 11:51:30 +08:00
想想要是 start_urls = ['a', 'b' , 'c', 'a'], 然后第二个被 filter 了也蛮爆炸的. 不过你要是实际用这种情况很少啦, 而且反正数据库也要做去重. 多抓一次其实影响不大.
nicevar
2018-03-01 13:11:27 +08:00
没太看明白这种写法为啥你会触发两次抓取,执行一次之后 spider 应该 close 了,难道你的意思是执行过程中产生了同样的 url 没有正常过滤?
我几个在跑的都是差不多写法,没有发现重复抓取现象
chengxiao
2018-03-01 13:16:51 +08:00
多谢楼主啊 我的几个爬虫经常出这个问题 我还纳闷这是什么情况
Nick2VIPUser
2018-03-01 13:43:31 +08:00
赞一个
qsnow6
2018-03-01 14:03:42 +08:00
有日志吗?看看日志不是清楚了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/433791

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX