V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
saximi
V2EX  ›  Python

看了 scrapy 官方说明文档,遇到几个问题恳请大家指点

  •  
  •   saximi · 2017-09-21 19:30:19 +08:00 · 2556 次点击
    这是一个创建于 2604 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看了 scrapy 0.25 官方说明文档,遇到几个问题,烦请大家指点,感谢!

    1、对于下面的 parse_item 方法,请问为什么要用 yield 返回,把 yield 删除,直接执行 scrapy.Request 会有何问题呢,或者是用 return 来返回 Request()又如何呢? 
    def parse_item(self, response): 
            item = MyItem()  
            yield scrapy.Request(item_details_url, self.parse_details, meta={'item': item}) 
    
    2、文档在描述“ CrawlSpider ”用法时警告到: 
    “当编写爬虫规则时,请避免使用 parse 作为回调函数。 由于 CrawlSpider 使用 parse 方法来实现其逻辑,如果 您覆盖了 parse 方法,crawl spider 将会运行失败。” 
    但是我看到有的爬虫程序中,参数用的是 CrawlSpider,并且自己重写了 parse 函数,在 parse 函数中用 yield 返回 Request 时,把 parse_item 作为回调函数,也是可以运行的。 
    这是否说明上面的警告其实是不正确的? 
    
    
    3、在描述“ CrawlSpider ”用法时还解释了对如下爬取规则的用法: 
    class scrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None) 
    文档提到:“ follow 是一个布尔(boolean)值,指定了根据该规则从 response 提取的链接是否需要跟进。 如果 callback 为 None,follow 默认设置为 True,否则默认为 False。” 
    我的问题是,如果 callback 为 None,这个时候对于链接要跟进,请问跟进是什么意思? 既然没有回调函数,那要如何处理当前页面呢? 
    
    4、关于下载器中间件,文档提到:“ DOWNLOADER_MIDDLEWARES 字典里的中间件会根据顺序(order)进行排序,最后得到启用中间件的有序列表: 第一个中间件是最靠近引擎的,最后一个中间件是最靠近下载器的”  
    我的问题如下: 
    首先,是否所有在字典里的中间件都一定会被调用,有没有可能只调用其中排在前面的某几个,而其余中间件的 process_request()方法不会被执行?如果是这样,什么情况下会如此? 
    
    其次,既然是按照顺序依序调用中间件,那为什么要强调靠近引擎和靠近下载器?这个说法有什么特殊意义么? 
    
    
    6 条回复    2017-09-21 23:21:02 +08:00
    mrzys
        1
    mrzys  
       2017-09-21 19:55:20 +08:00 via Android
    回答 1,使用 yield 的时候就是一个迭代器,可以不断 yield 新的 request,但是你用 return,就只会返回一个 request。
    mrzys
        2
    mrzys  
       2017-09-21 20:04:12 +08:00 via Android
    这里的 yield 的值可以是 request 也可以是一个 item,如果是一个 item 就会调用 pipeline,如果设置的话。这里应该是为了降低内存的使用率所以直接返回一个列表。另外不知道是不是使用协程来控制对 parse 方法的调用。
    PythonAnswer
        3
    PythonAnswer  
       2017-09-21 21:44:22 +08:00 via Android
    x. 可以用最新版的 scrapy

    x. parse 方法是设计好的,不要写个重名函数覆盖了。如果想重载,可以自己实现 parse 并加上想要的功能,但这不符合 scrapy 思想

    x. 中间件顺序,请参考 scrapy 架构图,那张十字排列的 png
    sunwei0325
        4
    sunwei0325  
       2017-09-21 21:50:24 +08:00
    现在都 1.4 了吧, 怎么还看这么古老版本的文档呢
    saximi
        5
    saximi  
    OP
       2017-09-21 22:32:36 +08:00
    @PythonAnswer 我用的 scrapy 是最新的,但是看的文档是 http://scrapy-chs.readthedocs.io/zh_CN/latest/ 这个网址的 0.25 中文版本,因为英文不好,所以只好看中文版本。
    那张 png 的图我看了,我知道中间件是按照右侧带的序号作为顺序来执行的,但是我不知道反正都是下载器中间件,为何要强调靠近引擎还是靠近下载器,这毕竟和执行顺序无关,做这个强调有什么意义么?
    PythonAnswer
        6
    PythonAnswer  
       2017-09-21 23:21:02 +08:00
    中间件是有顺序的,middleware 这个概念,你可以参考下 django 里面的 middleware,摆放都是有顺序的。

    比如做一碗阳春面。你抓来的数据只是面条,然后想煮成面。

    1. 碗里放盐和味精
    2. 放面条和汤
    3. 搅拌
    4. 撒上葱花点缀

    中间件的顺序可不能乱了,不然面条就不好看。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5578 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 01:45 · PVG 09:45 · LAX 17:45 · JFK 20:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.