python3编写网络爬虫20-pyspider框架的使用
二、pyspider框架的使用
简介 pyspider是由国人binux 编写的强大的网络爬虫系统 github地址 :
https://github.com/binux/pyspider
官方文档
http://docs.pyspider.org/
pyspider 带有强大的WebUI 脚本编辑器 任务监控器 项目管理器 以及结果处理器 支持多种数据库后端 多种消息队列 JavaScript
渲染页面的爬取 使用起来非常方便
1.基本功能
提供可视化编写和调试爬虫
爬虫项目管理能力
支持多种后端数据库
支持多种消息队列
提供优先级控制 失败重试 定时抓取等
支持单机的分布式部署
pyspider架构
主要分为Scheduler(调度器)Fetcher (抓取器) Processer (处理器) 三部分
整个爬取过程受到Monitor(监控器) 的监控 抓取结果被Result Worker (结果处理器) 处理
Scheduler 发起任务调度 Fetcher 负责抓取网页内容 Processer 负责解析网页 然后生成新的reuqest 发送给调度器 进行调度
生成的提取结果输出保存
pyspider的执行逻辑很清晰 如下:
1.每个pyspider的项目对应一个python脚本 脚本中定义Handler类 有一个on_start 方法 爬取首先调用 on_start() 生成最初的
抓取任务 然后发送给调度器
2.调度器将抓取任务分发给抓取器进行抓取 抓取器执行并得到响应 随后将响应发送给处理器
3.处理器处理响应并提取新的url生成新的抓取任务 然后通过消息队列的方式通知调度器 当前抓取任务执行情况 并将新生成的抓取
任务发送给调度器 如果生成新的抓取结果 则将其发送到结果队列等待 结果处理器处理
4.调度器收到新的抓取任务 查询数据库 判断新的抓取任务是否需要重新进行调度 然后发送给抓取器进行抓取
5.不断重复上面的工作 直到所有任务执行完毕 抓取结束
6.抓取结束后程序会回调 on_finished() 方法 这里可以定义后处理过程
2.基本使用
安装
pip install pyspider
如果报错 python setup.py egg.......pycurl
需要安装pycurl库 从 https://www.lfd.uci.edu/~gohlke/pythonlibs/#pycurl 找到对应版本的wheel文件 进行安装
验证安装
命令行 pyspider all
浏览器打开 http://localhost:5000/ 看到WebUI管理页面 表示安装成功
3.创建项目 (目标爬取 攻略的作者 标题 出发日期 人均费用 正文等保存)
新建项目 点击create 弹窗输入 项目名 和 爬取链接 点击create 就创建了一个项目
例如 qunar 链接 http://travel.qunar.com/travelbook/list.htm
会看到左侧是调试页面 点击左侧右上角run 单步调试爬虫 左侧下半部分可以预览 当前爬取的页面
右侧是代码编辑页面 可以直接编辑保存代码 不需要借助IDE工具
右侧已经生成了一段代码
from pyspider.libs.base_handler import * class Handler(BaseHandler):
crawl_config = {
} @every(minutes=24 * 60)
def on_start(self):
self.crawl('http://travel.qunar.com/travelbook/list.htm', 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(),
}
handler就是爬虫主类 可以在此处定义爬取 解析 存储的逻辑 整个代码只需要一个Handler即可完成
crawl_config属性 可以将项目的爬取配置统一定义 例如headers 设置代理 配置之后全局生效
on_start 爬虫入口 该方法通过调用 crawl() 方法即可新建一个爬取请求 第一个参数是爬取url callback 指定了爬取页面成功后
用哪个方法解析
index_page 接收response 参数 对接pyquery 直接调用doc 传入css选择器 代码中默认解析页面所有链接 然后遍历 再次调用crawl
生成新的爬取请求 同时指定callback 为 detail_page 意思是如果页面爬取成功了就调用detail_page 方法解析
这里实现两个功能 1.将爬取结果解析 2. 生成新的爬取请求
detail_page 接收resposne参数 抓取的是详情页 就不会生成新的请求 只做解析 解析后将结果以字典形式返回
4.爬取首页
点击run 看到下方follows 产生一个新的请求
左栏会出现当前run配置信息 这里有一个callback 为 on_start 说明点击run之后 实际执行了 on_start 方法
在 on_start 中利用 crawl 生成一个爬取请求
点击 follows 即可看到生成的爬取请求链接 每个链接右侧还有一个箭头
点击箭头 就可以对此链接进行爬取 也就是攻略首页
上方的 callback已经变成 index_page 代表运行了 index_page 方法 接收到的resposne 参数 就是第一个爬取请求的response对象
调用doc 传入css 选择器 获取a 节点属性 拿到第一个爬取页面所有链接 然后遍历 调用 crawl 把链接构造成新的请求
点击web 可预览爬取结果页面 结果和浏览器几乎一样结果
html 查看页面源代码
在 index_page 方法中提取了所有链接 并生成了新的爬取请求 但是爬取的肯定不是所有链接 只需要详情页就够了
修改一下当前index_page css选择器
可以借助另外一个工具
首先切换到Web页面 找到攻略标题 点击下方 enable css selector helper
在右侧选中要更改的区域
点击左栏右箭头 css选择器就替换成功了
重新run 就提取了当前页面10个攻略
还需要抓取后续页面
在 index_page 方法 添加如下代码
next = response.doc('.next').attr.href
self.crawl(next,callback = self.index_page)
利用css选择器 选中下一页 链接 获取href属性 也就获取了页面的URL 然后将URL传给Crawl 指定回调函数
注意这里回调函数仍然是index_page 因为下一页的结构与此页相同
重新run 就可以看到11个请求
索引列表页解析就完成了
5.爬取详情页
任选一个详情页进入 点击前10个爬取请求中的任意一个箭头 执行详情页爬取
切换到web 页面下拉 头图正文中的图片一直显示加载中
出现此现象的原因是pyspider默认发送http请求 请求文档本身不包含img 图片是经过js渲染的
pyspider 内部对接了Phantomjs 只需要修改一个参数即可
def index_page(self, response):
for each in response.doc('li > .tit > a').items():
self.crawl(each.attr.href, callback=self.detail_page,fetch_type='js')
next = response.doc('.next').attr.href
self.crawl(next,callback = self.index_page)
点击 左栏上方 返回箭头 重新调用 index_page 在点击新生成的详情页就可以看到了
最后将详情页需要的信息 提取出来
detail_page代码如下
def detail_page(self,response):
return{
'url' : response.url,
'title' : response.doc('#booktitle').text(),
'date' : response.doc('.when .data').text(),
'day' : response.doc('.howlong .data').text(),
'who' : response.doc('.who .data').text(),
'text' : response.doc('#b_panel_schedule').text(),
'image' : response.doc('.cover_img').attr.src
}
6.启动爬虫
返回爬虫主页面 将status 设置为DEBUG 或者 RUNNING 点击右侧RUN 即可开始爬取
在最左侧可以定义项目分组 方便管理 rate/burst 代表当前爬取速率 rate 代表1秒 发出多少请求
burst 相当于流量控制 rate和burst设置越大 爬取速率越快 (要考虑性能的IP被封)
Process中 5m 1h 1d 指最近5分 1小时 1天 all代表所有请求
蓝色代表等待执行请求
绿色代表成功请求
黄色代表失败 重试请求
红色代表失败过多 忽略请求
点击Active Tasks即可查看最近请求
点击results 即可查看爬取结果
点击右上角按钮 即可保存获取数据格式
更多参考资料 参考官方文档 http://docs.pyspider.org/
python3编写网络爬虫20-pyspider框架的使用的更多相关文章
- python3编写网络爬虫21-scrapy框架的使用
一.scrapy框架的使用 前面我们讲了pyspider 它可以快速的完成爬虫的编写 不过pyspider也有一些缺点 例如可配置化不高 异常处理能力有限对于一些反爬虫程度非常强的网站 爬取显得力不从 ...
- python3编写网络爬虫18-代理池的维护
一.代理池的维护 上面我们利用代理可以解决目标网站封IP的问题 在网上有大量公开的免费代理 或者我们也可以购买付费的代理IP但是无论是免费的还是付费的,都不能保证都是可用的 因为可能此IP被其他人使用 ...
- Python3编写网络爬虫12-数据存储方式五-非关系型数据库存储
非关系型数据库存储 NoSQL 全称 Not Only SQL 意为非SQL 泛指非关系型数据库.基于键值对 不需要经过SQL层解析 数据之间没有耦合性 性能非常高. 非关系型数据库可细分如下: 键值 ...
- Python3编写网络爬虫11-数据存储方式四-关系型数据库存储
关系型数据库存储 关系型数据库是基于关系模型的数据库,而关系模型是通过二维表保存的,所以它的存储方式就是行列组成的表.每一列是一个字段,每一行是一条记录.表可以看作某个实体的集合,而实体之间存在联系, ...
- python3编写网络爬虫23-分布式爬虫
一.分布式爬虫 前面我们了解Scrapy爬虫框架的基本用法 这些框架都是在同一台主机运行的 爬取效率有限 如果多台主机协同爬取 爬取效率必然成倍增长这就是分布式爬虫的优势 1. 分布式爬虫基本原理 1 ...
- python3编写网络爬虫22-爬取知乎用户信息
思路 选定起始人 选一个关注数或者粉丝数多的大V作为爬虫起始点 获取粉丝和关注列表 通过知乎接口获得该大V的粉丝列表和关注列表 获取列表用户信息 获取列表每个用户的详细信息 获取每个用户的粉丝和关注 ...
- python3编写网络爬虫19-app爬取
一.app爬取 前面都是介绍爬取Web网页的内容,随着移动互联网的发展,越来越多的企业并没有提供Web页面端的服务,而是直接开发了App,更多信息都是通过App展示的 App爬取相比Web端更加容易 ...
- python3编写网络爬虫14-动态渲染页面爬取
一.动态渲染页面爬取 上节课我们了解了Ajax分析和抓取方式,这其实也是JavaScript动态渲染页面的一种情形,通过直接分析Ajax,借助requests和urllib实现数据爬取 但是javaS ...
- Python3编写网络爬虫10-数据存储方式三-CSV文件存储
3.CSV文件存储 CSV 全称 Comma-Separated Values 中文叫做逗号分隔值或者字符分隔值,文件以纯文本形式存储表格数据.文件是一个字符序列 可以由任意数目的记录组成相当于一个结 ...
随机推荐
- SpringBoot解决ajax跨域问题
一.第一种方式: 1.编写一个支持跨域请求的 Configuration import org.springframework.context.annotation.Configuration; im ...
- C#.NET和C++结构体Socket通信与数据转换
最近在用C#做一个项目的时候,Socket发送消息的时候遇到了服务端需要接收C++结构体的二进制数据流,这个时候就需要用C#仿照C++的结 构体做出一个结构来,然后将其转换成二进制流进行发送,之后将响 ...
- [android] 获取系统的联系人信息
内容提供是实质上是个接口,后门,他给别人提供数据,系统联系人是个比较复杂的内容通过者. 找到/data/data/com.android.providers.contacts/contacts2.db ...
- [android] sharedPreference入门
/********************2016年5月6日 更新**************************************/ 知乎:Android 如何实现判断用户首次使用,比如首 ...
- Java学习笔记之——构造方法
构造方法:方法名和类名相同且没有返回值 1.作用 创建对象 对象初始化 2.普通方法的结构 权限修饰符 返回值类型 方法名(形参){ 方法体: } 3. 构造方法的结构 (1)结构 权限修饰符 方法名 ...
- Java静态数据的初始化
Java中无论创建多少对象,静态数据都只占一份存储区域. 下面程序示例静态存储区域的初始化: //: initialization/StaticInitialization.java // Speci ...
- JavaScript String常用方法和属性
在JavaScript中,字符串是不可变的,如果使用索引对字符串进行修改浏览器不会报错,但也没有任何效果.JavaScript提供的这些方法不会修改原有字符串的内容,而是返回一个新的期望的字符串. 一 ...
- jQuery效果之简单的手风琴效果
实现效果如图所示: html结构: <div class="item_box box10"> <div class="item_box_wp" ...
- cf997C. Sky Full of Stars(组合数 容斥)
题意 题目链接 \(n \times n\)的网格,用三种颜色染色,问最后有一行/一列全都为同一种颜色的方案数 Sol Orz fjzzq 最后答案是这个 \[3^{n^2} - (3^n - 3)^ ...
- Filter防止用户访问一些未被授权的资源
package com.drp.util.filter; import java.io.IOException; import javax.servlet.Filter; import javax.s ...