爬虫抓取的html缩进没了,PySpider踩坑记

PySpider

没有用过框架写爬虫,有人推荐了pyspider,我也没有和别的框架比对,就直接上手先用了。

使用感受

框架的封装性带来的优缺点在这里显示的淋漓精致...

优点

爬虫该有的都有了——网站入口;分页查询;解析网页;保存数据(还可以发消息);

爬取时间间隔设置;

网页有效期维护;

爬取多线程设置;

对无头浏览器phantomjs的支持;

支持web ui上调试代码,需求不高的情况下类似在线编写代码;

提供了一键式获取css selector按钮,方便获取元素。

缺点

本身不支持xpath方式解析;

使用回调方式来运行pipline,框架把控回调的执行,不够灵活,多层爬取时需要递归方式调用index_page,导致代码可能比较混乱;

提供的css selector提取器实用性一般,有一些复杂一点的拿不到;

任务运行/关闭很多时候令人迷惑;

对phantomjs的调用会对电脑cpu造成较大压力,据说是每次爬取都会启停一个phantomjs线程;

web ui没有删除任务的选项,也没有清空爬取到的数据的选项;

web ui的方式编码很费劲,我都是在IDE里面写好再复制上去;

web ui不能像本地IDE一样识别新加入的包。

版本:

pyspider v0.3.10

python 3.6.5

安装启动

# 一键安装pyspider

pip install pyspider

# 会在当前目录下建立data文件夹,保存任务相关代码,数据,任务进度等,如果换了路径启动就找不到了

# 启动所有pyspider的组件,更多命令可以 pyspider help

pyspider all

之后可以在 http://localhost:5000/ 看到启动了一个web ui,用来调试和运行pyspider的

框架机制补充

爬取

on_start并非只是个入口,pyspider之后要爬取url不会超过on_start执行的url的子集

换言之,不能爬取on_start的url的父路径。

多层次路径爬取

on_start只会执行一次,如果on_start中有循环调用crawl方法,则只会执行最后一条

index_page可以递归调用自身,可以使用这个特性来爬取多层路径

phantomjs

phantomjs 将其{phantomjs_home/bin}添加到环境变量path中即可,重启pyspider即可,注意要环境变量生效pyspider才能找到phantomjs。

浏览器中能获取到的dom,pyspider获取不到,可能是需要设置phantomjs的调用

一些小特性

这里不一一罗列API了,主要讲我使用过程中碰到的一些特性

from pyspider.libs.base_handler import *

# pyspider的实现类需要继承BaseHandler,实现基本的几个接口

class Handler(BaseHandler):

# 放一些self.crawl函数请求页面时的http请求头:referer,user-agent等

crawl_config = {

}

# pipline的起点,这里请求的url最好是下文请求的父级url,否则爬取不了,我出过这样的问题,不知道是不是就是这样的机制

# 只会执行一次,即如果on_start中有循环self.crawl,只会执行最后一次

@every(minutes=24 * 60) # 任务运行之间的间隔,用来不停的补采过期的数据

def on_start(self):

# 爬取网页的核心函数,支持phantomjs解析,需配置fetch_type='js'

self.crawl('http://scrapy.org/', callback=self.index_page)

# 理论上是爬取分页的,但是如果有多层爬取也得靠index_page,需要在self.crawl中设置callback为index_page,形成递归,当然如果逻辑不通,用if-else分开即可,如果有人发现了更好的多层爬取的方式,拜托告诉我一声...

@config(age=10 * 24 * 60 * 60) # 爬取结果的有效期

def index_page(self, response):

# response.doc得到一个pyquery对象,和操作一个jquery对象相似,相关api看pyquery官网即可

for each in response.doc('a[href^="http"]').items():

self.crawl(each.attr.href, callback=self.detail_page)

# 输出解析结果,如果用默认的sqlite,只能return一个dict,如果自己复写了on_result,就可以随意返回了

@config(priority=2)

def detail_page(self, response):

return {

"url": response.url,

"title": response.doc('title').text(),

}

# 自定义结果处理方式

def on_result(self, result):

...

# 处理结果

...

# task结束时调用

def on_finished(self, response, task):

...

# 任务关闭时的操作,可以用来关数据库连接之类

...

启停任务

在 localhost:5000 的web ui上修改状态即可

running和debug状态没有区别

rate/brust rate表示每秒爬取的网页个数可以为小数,这样可以放慢task调度,brust理解为并发数

其他

pyspider启动后在当前目录下生成data目录,project相关的数据,换目录启动会找不到之前的数据

pyspider自带了sqlite,但是要保存到别的数据库需要自己建连接,插入,关连接,相关的包自己导入后重启pyspider即可

project和task的信息在web-ui中不能修改,但是可以通过数据库工具打开data/{db_name}.db的文件,删除或者修改

可以通过web ui的result页面的on_process项的内容做简单的debug

phantomjs的环境变量有一种可以立即生效的办法,不赘述啦

web ui中看似好的缩进可能是不合法的, 编辑器问题,复制出来格式化好了再粘贴回去

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值