pyspider框架介绍
pyspider 是个强大的由python实现的爬虫系统。
纯python的
强大的webui,支持脚本编辑,任务监控,项目管理和pyspider 是个强大的由python实现的爬虫系统。结果查看
消息队列支持,RabbitMQ,Beanstalk,Redis以及Kombu
支持任务优先级,定时,失败重试等调度方案
分布式架构,抓取js页面
支持Python2和3
pyspider框架安装ubuntu
如果使用 ubuntu ,请先运行 sudo apt update ?再运行 sudo apt upgrade ?更新
apt-get?install?python?python-dev?python-distribute?python-pip?\ libcurl4-openssl-dev?libxml2-dev?libxslt1-dev?python-lxml?\ libssl-dev?zlib1g-dev
删除 wsgidav ?然后重新安装 2.4.1 版本
windows
https://HdhCmsTestlfd.uci.edu/~gohlke/pythonlibs/ 中下载 pycurl 安装
windows 下安装成功,运行报如下错误:
?Deprecated?option?'domaincontroller':?use?'http_authenticator.domain_controller'?instead.
解决方案:
删除 wsgidav ?然后重新安装 2.4.1 版本
pypsider入门
安装好 pyspider 后,创建一个项目文件夹用来存放相关文件,进入文件夹后运行 pyspider 命令,默认情况下会运行一个web服务端监听5000端口,通过 http://localhost:5000 即可访问pyspider的web管理界面,它看起来是这样的:
项目是独立的,但您可以将另一个项目作为模块导入 from projects import other_project 一期工程有5个状态:TODO,STOP,CHECKING,DEBUG和RUNNING
TODO - 创建一个脚本来编写
STOP- 您可以将项目标记为STOP您希望它停止(= =)。
CHECKING- 修改正在运行的项目时,为防止不完整修改,项目状态将CHECKING自动设置。
DEBUG/ RUNNING- 这两种状态对蜘蛛没有区别。但是将它标记为DEBUG第一次运行然后将其更改RUNNING为检查后是很好的。
抓取速度被控制,rate并burst用令牌桶算法。
rate - 一秒钟内有多少请求
burst- 考虑到这种情况,rate/burst = 0.1/3这意味着蜘蛛每10秒抓一页。所有任务都已完成,项目每分钟检查最后更新的项目。假设找到3个新项目,pyspider将“爆发”并抓取3个任务而不等待3 * 10秒。但是,第四项任务需要等待10秒。 要删除项目,请设置group为delete和状态STOP,等待24小时。
爬取目标(链家网)
因为我身处东莞,所以爬取的是东莞的
https://dg.lianjia测试数据/ershoufang/
新建项目
进入到了开发界面
def on_start(selef) 是脚本的入口。当你点击 run 按钮时,它会被调用。
self.crawl(url, callback=self.index_page) 是最重要的接口。它会添加一个新的待爬取任务。大部分的设置可以通过 self.crawl 的参数去指定。
def index_page(self, response) 接收一个response对象。 response.doc 是一个 pyquery 对象,它有一个类似 jQuery 选择器一样的接口,去解析页面元素。
def detail_page(self, response) 返回一个字典结果。这个结果默认会被写入 resultdb (结果数据库)。你可以通过复写 on_result(self, result) 方法来按照你自己的需求处理结果。
@every(minutes=24 * 60) 这个装饰器会告诉调度器, on_start 方法将会每天被调用。
@config(age=10 * 24 * 60 * 60) 指定当 self.crawl 爬取的页面类型为 index_page (当 callback=self.index_page )时的age参数的默认值。参数 age 可以通过 self.crawl(url, age=10 24 60*60) 和 crawl_config 来指定,直接在方法参数中指定具有最高的优先级。
age=10 24 60*60 告诉调度器抛弃10天内爬取过的请求。默认情况下,相同URL不会被爬取两次,甚至你修改了代码。对于初学者来说,第一次运行项目然后修改它,在第二次运行项目的情况非常常见,但是它不会再次爬行(阅读 itag 了解解决方案)
@config(priority=2) 标志着, detail page 将会被优先爬取。
你可以通过点击绿色的 run 按钮,一步一步的调试你的脚本。切换到 follows 面板,点击 play 按钮前进。
注意点 :
在使用 self.crawl ?函数时必须加上 validate_cert=False ?保证能够爬取https,不然会报599,SSL 错误解决办法
想要爬取js生成的东西,需要使用 PhantomJS ,下载 PhantomJS.exe 丢掉· python.exe 同路径下,通过添加参数 fetch_type='js' 来启用此功能self.crawl
由于链家网没有使用js生成数据,所以没有加上 fetch_type='js' ,当我运行,得到了链家网首页 364条a标签的链接
获取需要url所在的xpath路径
在重新crawl方法,我们可以看出title和url的输出,说明没有问题
对于pyspider还有一个简介的方法就是通过css选择器来获取对应的css路径,从下面可以看出代码没有问题
入库
对于入库需要写 on_result 方法和初始化方法具体如下
不到半分钟,数据爬取完毕
#!/usr/bin/env?python #?-*-?encoding:?utf-8?-*- #?Created?on?2019-07-21?17:08:14 #?Project:?lianjia from?pyspider.libs.base_handler?import?* from?lxml?import?etree import?pymysql class?Handler(BaseHandler): ????crawl_config?=?{ ????} ????def?__init__(self): ????????db_config?=?{ ????????????'host':?'',?#ip ????????????'user':?'',?#账号:不能用root的账号 ????????????'password':?'', ????????????'db':?'',? ????????????'charset':?'utf8', ????????????'port':?3306? ????????} ????????self.db?=?pymysql.connect(**db_config)? ????????self.cur?=?self.db.cursor() ????????#?创建表items ????????sql1?=?'create?table?if?not?exists?items?(url?varchar(255)?NOT?NULL?,title?VARCHAR(255)?NOT?NULL,?price?VARCHAR(255)?NOT?NULL,?content?mediumblob?NOT?NULL,?Introduce?mediumblob?NOT?NULL)?' ????????self.cur.execute(sql1) ????????print('数据库创建成功') ????@every(minutes=24?*?60) ????def?on_start(self): ????????#?通过迭代来不断的访问新的链接 ????????for?i?in?range(1,101): ????????????self.crawl('https://dg.lianjia测试数据/ershoufang/{}'.format(i),?callback=self.index_page,validate_cert=False) ????@config(age=10?*?24?*?60?*?60) ????def?index_page(self,?response): ????????xml?=?etree.HTML(response.text) ????????urls?=?xml.xpath('//ul[@class="sellListContent"]//li/a/@href') ????????#?获取每页的li中的url ????????print(urls)?#列表 ????????#for?each?in?response.doc('a[href^="http"]').items(): ????????????#self.crawl(each.attr.href,?callback=self.detail_page,validate_cert=False)???? ????????for?url?in?urls: ????????????self.crawl(url,?callback=self.detail_page,validate_cert=False) ????@config(priority=2) ????def?detail_page(self,?response): ????????#?爬取对应的title,url,?pricecontent和Introduce ????????return?{ ????????????"url":?response.url, ????????????"title":?response.doc('title').text(), ????????????"price":?str(response.doc('.price?>?.total').text())?+?'万', ????????????"content":?response.doc('.base').text(), ????????????"Introduce":response.doc('.baseattribute?>?.content').text() ????????} ????@config(priority=2) ????def?on_result(self,?result): ????????sql?=?'insert?into?items(url,title,price,content,Introduce)?values(%s,?%s,%s,%s,%s)' ????????try: ????????????if?result['url']: ????????????????self.cur.execute(sql,?(result['url'],?result['title'],result['price'],?result['content'],result['Introduce'])) ????????except?Exception?as?e: ????????????self.db.rollback() ????????????print(e) ????????else: ????????????self.db测试数据mit()
不到半分钟爬取了1146条数据,但是有的数据的重复的,应该用集合来去重
■ Over?■
最后,祝有所学习,有所成长
回复【 1024 】获取学习资料
转发,好看支持一下,感谢
你的转发,就是对我最大的支持
查看更多关于爬虫篇| pyspider 爬取链家网(八)的详细内容...