干货|理解Python爬虫框架pyspider
Posted AI遇见机器学习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了干货|理解Python爬虫框架pyspider相关的知识,希望对你有一定的参考价值。
原创干货,第一时间送达
一、pyspider简介
pyspider是Binux做的一个爬虫架构的开源化实现,主要功能有 :
抓取、更新调度多站点的特定的页面
需要对页面进行结构化信息提取
灵活可扩展,稳定可监控
pyspider以去重调度,队列抓取,异常处理,监控等功能作为框架,只需提供给抓取脚本,并保证灵活性。最后加上web的编辑调试环境,以及web任务监控,即成为了这套框架。pyspider的设计基础是:以python脚本驱动的抓取环模型爬虫
各个组件间使用消息队列连接,除了scheduler是单点的,fetcher 和 processor 都是可以多实例分布式部署的。 scheduler 负责整体的调度控制
任务由 scheduler 发起调度,fetcher 抓取网页内容, processor 执行预先编写的python脚本,输出结果或产生新的提链任务(发往 scheduler),形成闭环
每个脚本可以灵活使用各种python库对页面进行解析,使用框架API控制下一步抓取动作,通过设置回调控制解析动作
二、pyspider界面
在终端输入pyspider all 运行pyspider服务,然后再浏览器中输入 localhost:5000 即可看到pyspider的界面,rate 用于控制每秒抓取页面的个数,burst 可以视为并发控制。如果要删除项目则需要将group设置为delete,status设置为stop,24小时候项目就会删除。
点击create可以创建项目
点击刚创建的项目打开脚本编辑界面
我们可以在这里编写并调试脚本,测试时web可以显示网页,web左边的按钮为css选择器,html为网页的源代码,follows显示可以爬取的url,具体的调试亲身体验过就知道了。
三、pyspider脚本
但你创建新的工程的时候你会看到这些默认的脚本模板,接下来为大家简单介绍pyspider脚本的编写。
from pyspider.libs.base_handler import *class Handler(BaseHandler):
crawl_config = {
}
@every(minutes=24 * 60) def on_start(self):
self.crawl('__START_URL__', callback=self.index_page)
@config(age=10 * 24 * 60 * 60) def index_page(self, response): for each in response.doc('a[href^="http"]').items():
self.crawl(each.attr.href, callback=self.detail_page)
@config(priority=2) def detail_page(self, response): return { "url": response.url, "title": response.doc('title').text(),
}
crawl_config:爬虫的全局参数设置,例如请求头和cookies可以在这里设置(传入关键字及对应的参数即可)
on_start(self):爬虫开始爬取的入口
crawl:和requests有相同的功能 ,可以支持 get(默认) 和 post,常用的参数有
data 是想要提交数据
callback 可以在执行完 crawl后调用回调函数
method 是指定 访问方法
files 上传文件,{'key': ('file.name': 'content')}
headers 请求头,类型dict
cookies 请求的 Cookies 类型 dict
timeout 请求内容里最大等待秒数.默认值:120
connect_timeout : 指定请求时链接超时时间,单位秒,默认值:20
proxy : 可以设置代理服务器,暂时只支持http代理
更多参数使用可以查看官方文档。
response
crawl :返回的对象是 response 对象
response.text : 请求响应的文本格式内容**(如果Response.encoding 是 None 或 chardet 模块可用, 响应内容会自动被解析为指定的编码)**
response.doc : 本方法会调用PyQuery库用返回的内容生成一个PyQuery对象以方便使用,生成对象时默认已经把里面的所有链接格式化成绝对链接,可直接分析使用(具体使用对象方法可以参考PyQuery官方参考手册)
response.json : 本方法会调用JSON相关库来解析返回的内容
response.status_code : 返回响应的状态码
response.headers : 请求响应的头信息,dict格式
response.cookies : 响应的cookies
response.time : 抓取使用的时间
index_page和detail_page只是初始脚本中的回调函数,除了on_start,其他的函数名可以自定
@every(minutes=24 * 60) 设置多久执行一次(24*60为一天一次,因此可以每天都爬一次获取数据)
@config
age 设置任务的有效期限,在这个期限内目标爬取的网页被认为不会进行修改,以秒为单位
priority 设定任务优先级
auto\_recrawl 设置是否每到age时间重新爬取一次,默认值是:False
priority 这个参数用来指定任务的优先级,数值越大越先被执行,默认值为 0
retries 任务执行失败后重试次数,默认值是 3
itag 任务标记值,此标记会在抓取时对比,如果这个值发生改变,不管有效期有没有到都会重新抓取新内容.多数用来动态判断内容是否修改或强制重爬,默认值是 None
mac os 安装pyspider的坑(不是mac系统的朋友可以忽略)
mac系统下安装pyspider时你可能会遇到pycurl的导入错误
ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (none/other)
这个问题可以通过重装pycurl解决,但是在高版本的mac系统中的系统环境变量是不存在openssl的头文件的。在终端输入以下指令则可以解决问题
pip uninstall pycurl# 卸载库
export PYCURL_SSL_LIBRARY=openssl
export LDFLAGS=-L/usr/local/opt/openssl/lib
export CPPFLAGS=-I/usr/local/opt/openssl/include# openssl相关头文件路径
pip install pycurl --compile --no-cache-dir# 重新编译安装
系统环境:Mac High Sierra 10.13.2
四、特殊技巧
模拟登录
有很多网站需要登录之后才能浏览更多的内容,因此我们的爬虫需要实现模拟登录的功能,我们可以通过 selenium 来实现模拟登录。
selenium 是一个用于Web应用程序测试的工具,同时我们也可以通过 selenium 实现登录功能。以微博为例
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://weibo.com/")
username = driver.find_element_by_css_selector("input#loginname")
username.clear()
username.send_keys('your_username')
password = driver.find_element_by_css_selector('span.enter_psw')
password.clear()
password.send_keys('your_password')
在输入账号和密码后,最大的问题来了,验证码都是图片,一般我们要借助图像识别才能识别验证码,但是由于验证码的种类非常多(英文、数字、中文或者它们的混合),而且验证码还可能被一定的旋转、扭曲甚至互相粘连,以至于人眼也不能很好的辨认,因此大多数模型的通用性和准确率并不是很高。因此效率最高的方法就是在selenium打开浏览器之后手动登录(过程中调用time.sleep()暂停程序)。因为对于爬虫来说最重要的不是解决登录问题,因此这么做可以节约大量的时间以及代码量,虽然很蠢,但是很有用。
完成登录后,用一下代码即可获取cookie,并把cookie_dict传给pyspider全局参数中的cookies即可
cookies_dict = {}
cookies = driver.get_cookies()
for cookie in cookies:
cookies_dict[cookie['name']] = cookie['value']
JS
普通的requests请求只能抓取静态HTML网页, 但是大部分网站都是混入了JS数据加载,数据是延迟加载的,想要抓取这些内容可以使用selenium + PhantomJS完全渲染网页后再进行网页解析。PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎,使用方法和使用selenium + Chrome模拟登录是类似的,但由于PhantomJS没有界面因此内存消耗会少很多。
爬取AJAX异步加载网页
AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。爬取AJAX异步加载的网页我们要去分析网页的发出的请求以及返回的信息。具体的我们要使用Google浏览器的开发者工具(火狐还有其他浏览器也有这个)查看网络的XHR那里,但网页局部更新的时候,浏览器发出了什么请求,并且查看浏览器返回来什么。
在我们微博登录后的主页,只要把滚动条移动到最下面就会发现会刷出新的微博,这是我们打开开发者工具,不断的往下滚,然后你会发现但你刷出新的信息时总会发出一个新的请求,并且它返回的json中data为刷新微博的html。
仔细观察发现其中pagebar这里的变化有规律,并且id减少了15对应了新刷出的15条微博。因此可以推测pagebar应该是刷出新微博的关键。在这之前我们要给爬虫加一个请求头部,否则很有可能被服务器识别为机器人而无法成功访问。请求头同样可以在开发者工具那里找到。
def on_start(self):
for i in range(10):
url = 'https://weibo.com/aj/mblog/fsearch?pagebar=%s'%i
self.crawl(url, callback=self.index_page)
发现成功爬取并返回了微博的内容。接下来只需对你所需要的信息进行处理即可。
以上是关于干货|理解Python爬虫框架pyspider的主要内容,如果未能解决你的问题,请参考以下文章
Python爬虫新手教程:手机APP数据抓取 pyspider