爬虫 pyspider 学习笔记 - V2EX
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
laoyuan
V2EX    Python

爬虫 pyspider 学习笔记

  •  
  •   laoyuan
    laoyuan 2015-04-29 15:39:39 +08:00 9648 次点击
    这是一个创建于 3824 天前的主题,其中的信息可能已经有所发展或是发生改变。
    文档: http://docs.pyspider.org/
    版本:pyspider 0.3.4
    环境:Mac OS X 10.10


    Docs Introduction

    代码部分看了个大概意思,就是把http://scrapy.org/ 页面上的所有a href= 链接抽取成{url, title} 字典。

    Docs Quickstart

    安装和启动都很傻瓜。

    关于callback:
    查了一下大概就是把callback 前边的参数传给callback 这个函数来处理的意思。
    self.crawl('http://scrapy.org/', callback=self.index_page)
    翻译过来就是 self.index_page(self.crawl('http://scrapy.org/')),把页面抓下来交给index_page() 处理。

    使用WebUI:
    create 一个项目,以默认脚本为例,点run,这时并没有开抓,只是添加了一条url 而已,点下面的follows 可以看到这条,然后点链接后面的三角开始第一次抓取,也就是执行index_page(),得到了18条新链接,点任意一条的三角,就是对这个链接执行detail_page(),右下角可以看到detail_page() return 的结果了。注意run 所在的绿色框内的内容变化,run 下面的前进后退相当于切换run 的内容:on_start、index_page、detail_page。

    这节文档里有很多备注*,挨个点开看一眼,不明白也没关系,尽量多的弄明白,尤其是Response,它就是crawl() 爬到的结果,修改detail_page() 把Response 的每一项都return 出来看看(其实可以在return 之前print 出来看)。

    Docs Command Line

    不是很明白,大体过了一遍。

    Docs Level 1: HTML and CSS Selector

    这个例子中实际detail_page() 这一步没有必要,index_page() 得到的页面就可以抽取到足够的信息了,如何一次crawl() 生成多个result 我还在研究。将例子运行起来之后,发现数据保存在执行pyspider 命令行所在目录下data 文件夹内,sqlite 格式。做web 还是得保存到MySQL 里,转到学习文档Deployment。

    Docs Deployment

    装好RabbitMQ,-detached 方式运行起来,安装pyspider[all],编辑好config.json 就可以运行了。之前没用Python 连过MySQL,结果没跑起来,结合错误信息将 /Library/Python/2.7/site-packages/mysql/connector/connection.py
    self._unix_socket = '/tmp/mysql.sock' 这一行配置下就好了。
    在MySQL 环境把Level 1 重新过一遍,可以发现webUI 项目页面的操作仅相当于调试并没有保存结果,在项目列表页把status 改为runnig 再点run,才是真正启动爬虫,数据入库。

    Docs Level 2: AJAX and More HTTP

    这一节的示例代码解答了Level 1 提出来的问题:一次crawl() 只能打包成一个result。同时这一节带来更多问题:如何自定义header、使用cURL、POST。

    Docs Level 3: Render with PhantomJS

    安装PhantomJS,Deployment 里给出的config.json 示例漏掉了一行:"phantomjs_proxy": "localhost:25555", 否则尽管localhost://25555 能访问,crawl() 仍然报501错误。第一个例子有时候能得到结果有时候不能,网络原因吧。

    Docs Architecture

    主要弄明白了Processor 是干什么的。既然是异步的,不知道Fetcher 得到的结果暂时存放在哪里,假如很多Fetcher 在工作,Processor 或者result_worker 来不及处理会不会爆仓?可能Processor 处理的速度和Fetcher 抓页面不在一个数量级上,永远都不会爆。

    Docs About Projects

    burst 大概就是从闲着没活可干到来活了,开干的那一下可以几个页面一块抓的意思。

    Docs Script Environment

    抓一个不存在的页面,测试下 @catch_status_code_error,试试print

    Docs self.crawl

    重点来了,先测试下header:
    headers={"User-Agent": "aaa"} 抓一下 http://headers.cloxy.net/request.php ,然后在 index_page() 里直接print response.text 看结果。发现headers 参数放在@config 里不好使,放在crawl_config 里可以。
    再测试下post:method="POST", data="xxx"
    另外age 的解释应该是 don't re-crawl if last_crawl_time + age < now. 少了个don't

    Docs Response

    有些不知道干嘛的没关系了,有Response.text 基本就够了。

    Docs self.send_message

    这一课才真正解决了Level 1 提出来的问题!原来一个url 只能对应一个result!
    第 1 条附言    2015-05-24 18:51:02 +08:00
    'Accept-Encoding': 'gzip, deflate' 遭遇 fetch_type='js',CentOS 7 乱码,Mac 直接PhantomJS crash
    总之fetch_type='js' 时,header 不可设gzip
    6 条回复    2015-11-15 10:24:04 +08:00
    binux
        1
    binux  
       2015-04-29 19:02:19 +08:00   2
    1. @config 作用的是「以 @config 修饰的 method 为 callback 的 crawl 请求」。也就是说,@config 是以抓取的页面类型,而不是前链的页面类型来作用的。
    2. Fetcher 到的结果,会通过消息队列给 Processor,队列大小可以设置。
    3. 一个 callback 可以通过 yield 返回多个结果,只不过,只有最后一个会被保存到 resultdb 中。需要重载 result_worker 或者 on_result 自行处理多个结果的情况。
    laoyuan
        2
    laoyuan  
    OP
       2015-04-29 21:36:52 +08:00
    @binux 感谢指点!
    明天抓虾米,把我200多个好友收藏的音乐跑下来看谁收歌和我最接近,最近闹歌荒!
    laoyuan
        3
    laoyuan  
    OP
       2015-05-04 14:08:11 +08:00
    @binux 抓虾米的快写好了,目前比较郁闷的地方就是webUI 脚本窗口没有行号,出错了还要去数。。
    laoyuan
        4
    laoyuan  
    OP
       2015-05-09 15:02:24 +08:00
    headers 设置为空的方法:
    crawl_cOnfig= {
    'headers': {
    'User-Agent': '',
    'Accept': '',
    'Accept-Encoding': '',
    },
    }
    udumbara
        5
    udumbara  
       2015-11-15 01:38:50 +08:00
    关于 send_message()请教下,在 debug 界面可以正常显示出 message 数量,点开也可以显示内容,但是点 run 却没有反应,不知道您是怎么设置的,方便给过样例么?谢谢
    laoyuan
        6
    laoyuan  
    OP
       2015-11-15 10:24:04 +08:00
    @udumbara
    文档里的案例就可以啊。我自己写的用 send_message 来触发一批新的抓取任务

    send_message(self.project_name, ar_url)

    def on_message(self, project, ar_url):
    ....for url in ar_url:
    ........self.crawl(url 。。。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5391 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 07:49 PVG 15:49 LAX 00:49 JFK 03:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86