WebMagic 爬虫技术
WebMagic
WebMagic 介绍
WebMagic基础架构
Webmagic 的结构分为 Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由 Spider将他们彼此组织起来。这四种组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。Spider将这几个组件组织起来,让他们可以互相交互,流程化的执行,可以认为Spider是一个大容器,也是WebMagic逻辑的核心。架构图如下:
WebMagic 的四大组件
Downloader:负责从互联网下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。
PageProcessor:负责解析页面,抽取有用信息,以及发现新的链接。WebMagic 使用 Jsoup 作为 HTML 解析工具,并基于其开发了解析 XPath 的工具 Xsoup。
Scheduler:负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理 URL,并用集合来进行去重。也支持使用Redis 进行分布式管理。
Pipeline:负责抽取结果的结果,包括计算、持久化到文件、数据库等。WebMagic 默认提供了“输出到控制台”和“保存到文件”两个结果处理方案。
用于数据流转的对象
Request:是对 URL 地址的一层封装,一个 Request 对应一个 URL 地址。它是 PageProcessor 与 Downloader 交互的载体,也是 PageProcessor 控制 Downloader 唯一方式。在这里插入代码片
Page:代表了从 Downloader 下载到的一个页面 – 可能是 HTML,也可能 JSON 或者其他文本格式的内容。Page 是 WebMagic 抽取过程的核心对象,它提供一些方法可供抽取、结果保存等。
ResultItems:相当于一个 Map,它保存 PageProcessor 处理的结果,供 Pipeline 使用。(当字段 skip 设置为 true,则不应被 Pipeline 处理)
WebMagic 功能
实现 PageProcessor
抽取元素 Selectable
WebMagic 里主要使用了三种抽取技术:Xpath、正则表达式和 css选择器。另外,对于 JSON 格式的内容,可使用 JsonPath 进行解析。
Xpath:
page.getHtml().Xpath("//div[@class=mt]/h1/text()")
CSS 选择器:
page.getHtml().css("div.p_in li.bk")
正则表达式:
html.css("div.t1 span").regex(".*发布")
抽取元素 API
当链式调用结束时,我们一般都想要拿到一个字符串类型的结果。这时候就需要用到获取结果的API了。
方法 | 说明 | 示例 |
---|---|---|
xpath(String xpath) | 使用XPath选择 | html.xpath("//div[@class=‘title’]") |
$(String selector) | 使用Css选择器选择 | html.$(“div.title”) |
$(String selector,String attr) | 使用Css选择器选择 | html.$(“div.title”,“text”) |
css(String selector) | 功能同$(),使用Css选择器选择 | html.css(“div.title”) |
links() | 选择所有链接 | html.links() |
regex(String regex) | 使用正则表达式抽取 | html.regex("(.*?)") |
获取结果 API
方法 | 说明 | 示例 |
---|---|---|
get() | 返回一条String类型的结果 | String link= html.links().get() |
toString() | 返回一条String类型的结果 | String link= html.links().toString() |
all() | 返回所有抽取结果 | List links= html.links().all() |
☆ 当有多条数据的时候,使用get()和toString()都是获取第一个url地址;all()则会获取到所有元素。
获取链接
// 获取下一列的url
String bkUrl = page.getHtml().css("div.p_in li.bk").nodes().get(1).links().toString();
// 把url放到任务队列中
page.addTargetRequest(bkUrl);
使用 Pipeline 保存结果
WebMagic用于保存结果的组件叫做 Pipeline
保存到文件中
public static void main(String[] args) {
Spider.create(new JobProcessor())
//初始访问url地址
.addUrl(url)
.addPipeline(new FilePipeline("D:/webmagic/"))
.thread(5)//设置线程数
.run();
}
保存到数据库中
@Autowired
private SpringDataPipeline springDataPipeline;
// initialDelay:当任务启动后,等等多久执行方法
// fixedDelay:每隔多久执行方法
@Scheduled(initialDelay = 1000,fixedDelay = 10000)
public void process(){
Spider.create(new JobProcess())
.addUrl(url)
.thread(10)
.addPipeline(springDataPipeline)
.run();
}
SpringDataPipeline 类
@Component
public class SpringDataPipeline implements Pipeline {
@Autowired
private JobInfoService jobInfoService;
@Override
public void process(ResultItems resultItems, Task task) {
//获取封装好的招聘详情对象
JobInfo jobInfo = resultItems.get("jobInfo");
//判断数据是否不为空
if (jobInfo != null) {
//如果不为空把数据保存到数据库中
this.jobInfoService.save(jobInfo);
}
}
}
爬虫的配置、启动和终止
Spider
Spider 是爬虫启动的入口。在启动爬虫之前,我们需要使用一个 PageProcessor 创建一个 Spider 对象,然后使用 run() 启动。
public void process(){
Spider.create(new JobProcess())
...
.run();
}
方法 | 说明 | 示例 |
---|---|---|
create(PageProcessor) | 创建Spider | Spider.create(new GithubRepoProcessor()) |
addUrl(String…) | 添加初始的URL | spider .addUrl(spider .addUrl(“https://www.baidu.cn/”)) |
thread(n) | 开启n个线程 | spider.thread(5) |
run() | 启动,会阻塞当前线程执行 | spider.run() |
start()/runAsync() | 异步启动,当前线程继续执行 | spider.start() |
stop() | 停止爬虫 | spider.stop() |
addPipeline(Pipeline) | 添加一个Pipeline,一个Spider可以有多个Pipeline | spider .addPipeline(new ConsolePipeline()) |
setScheduler(Scheduler) | 设置Scheduler,一个Spider只能有个一个Scheduler | spider.setScheduler(new RedisScheduler()) |
setDownloader(Downloader) | 设置Downloader,一个Spider只能有个一个Downloader | spider .setDownloader(new SeleniumDownloader()) |
get(String) | 同步调用,并直接取得结果 | ResultItems result = spider.get(“http://webmagic.io/docs/”) |
getAll(String…) | 同步调用,并直接取得一堆结果 | List results = spider .getAll(“http://webmagic.io/docs/”, “http://webmagic.io/xxx”) |
爬虫配置Site
Site.me()可以对爬虫进行一些配置配置,包括编码、抓取间隔、超时时间、重试次数等。
private Site site = Site.me()
.setCharset("gbk")//设置编码
.setTimeOut(10 * 1000)//设置超时时间
.setRetrySleepTime(3000)//设置重试的间隔时间
.setRetryTimes(3);//设置重试的次数
方法 | 说明 | 示例 |
---|---|---|
setCharset(String) | 设置编码 | site.setCharset(“utf-8”) |
setUserAgent(String) | 设置UserAgent | site.setUserAgent(“Spider”) |
setTimeOut(int) | 设置超时时间,单位是毫秒 | site.setTimeOut(3000) |
setRetryTimes(int) | 设置重试次数 | site.setRetryTimes(3) |
setCycleRetryTimes(int) | 设置循环重试次数 | site.setCycleRetryTimes(3) |
addCookie(String,String) | 添加一条cookie | site.addCookie(“dotcomt_user”,“code4craft”) |
setDomain(String) | 设置域名,需设置域名后,addCookie才可生效 | site.setDomain(“github.com”) |
addHeader(String,String) | 添加一条addHeader | site.addHeader(“Referer”,“https://github.com”) |
setHttpProxy(HttpHost) | 设置Http代理 | site.setHttpProxy(new HttpHost(“127.0.0.1”,8080)) |
WebMagic 爬虫技术的更多相关文章
- 总结整理 -- 爬虫技术(C#版)
爬虫技术学习总结 爬虫技术 -- 基础学习(一)HTML规范化(附特殊字符编码表) 爬虫技术 -- 基本学习(二)爬虫基本认知 爬虫技术 -- 基础学习(三)理解URL和URI的联系与区别 爬虫技术 ...
- 爬虫技术 -- 基础学习(四)HtmlParser基本认识
利用爬虫技术获取网页源代码后,针对网页抽取出它的特定文本内容,利用正则表达式和抽取工具,能够更好地抽取这些内容. 下面介绍一种抽取工具 -- HtmlParser HtmlParser是一个用来解析H ...
- 爬虫技术浅析 | WooYun知识库
爬虫技术浅析 | WooYun知识库 爬虫技术浅析 好房通ERP | 房产中介软件最高水准领导者 undefined
- 爬虫技术实战 | WooYun知识库
爬虫技术实战 | WooYun知识库 爬虫技术实战 大数据分析与机器学习领域Python兵器谱-大数据邦-微头条(wtoutiao.com) 大数据分析与机器学习领域Python兵器谱
- 爬虫技术浅析 | z7y Blog
爬虫技术浅析 | z7y Blog 爬虫技术浅析
- .net 爬虫技术
关于爬虫 从搜索引擎开始,爬虫应该就出现了,爬的对象当然也就是网页URL,在很长一段时间内,爬虫所做的事情就是分析URL.下载WebServer返回的HTML.分析HTML内容.构建HTTP请求的模拟 ...
- 使用webcollector爬虫技术获取网易云音乐全部歌曲
最近在知乎上看到一个话题,说使用爬虫技术获取网易云音乐上的歌曲,甚至还包括付费的歌曲,哥瞬间心动了,这年头,好听的流行音乐或者经典老歌都开始收费了,只能听不能下载,着实很郁闷,现在机会来了,于是开始研 ...
- 使用htmlparse爬虫技术爬取电影网页的全部下载链接
昨天,我们利用webcollector爬虫技术爬取了网易云音乐17万多首歌曲,而且还包括付费的在内,如果时间允许的话,可以获取更多的音乐下来,当然,也有小伙伴留言说这样会降低国人的知识产权保护意识,诚 ...
- 利用python的爬虫技术爬去糗事百科的段子
初次学习爬虫技术,在知乎上看了如何爬去糗事百科的段子,于是打算自己也做一个. 实现目标:1,爬取到糗事百科的段子 2,实现每次爬去一个段子,每按一次回车爬取到下一页 技术实现:基于python的实现, ...
随机推荐
- itoa函数递归实现
库函数中有atoi函数,用意是将字符形式输入的数据转换成数字,而库函数有没有提供一个将数字转换成字符的函数呢?答案是有的,而且功能很是强大,那就是sprintf().snprintf()格式化转换函数 ...
- 自旋锁&信号量
1. 自旋锁 Linux内核中最常见的锁是自旋锁.一个自旋锁就是一个互斥设备,它只能有两个值:"锁定"和"解锁".如果锁可用,则"锁定"位被 ...
- jQuery中的常用方法:empty()、each()、$.each()、$.trim()、focus()(二)
<!DOCTYPE html> <html> <head> <title>02_commonMethod.html</title> < ...
- RabbitMq四种模式介绍和授权
rabbitmqctl change_password admin admin123 修改admin密码 界面管理和授权操作 1新增用户 rabbitmqctl add_user admin amin ...
- 「萌新指南」SOA vs. 微服务:What’s the Difference?
实话实说,在我还没有实习之前,我是连 SOA 是啥都不知道的,只听说过微服务,毕竟微服务实在太火了,想不知道都难,我觉得实习的时候肯定也是微服务,进组之后发现是 SOA 架构,当时都懵了,看了很多文档 ...
- Spring依赖注入的四种方式
首先,我们需要定义一个Bean的class类: package framework.spring; import org.springframework.beans.BeansException; i ...
- 痞子衡嵌入式:MCUXpresso IDE下工程链接文件配置管理与自动生成机制
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下工程链接文件配置管理与自动生成机制. 痞子衡在 2018 年初写过一个专题 <嵌入式开发文件系列&g ...
- Vs code自动生成Doxygen格式注释
前言 程序中注释的规范和统一性的重要性不言而喻,本文就推荐一种在用vscode编写代码时自动化生成标准化注释格式的方法,关于Doxygen规范及其使用可查看博文 代码注释规范之Doxygen. ...
- python3 spider [ urllib.request ]
# # 导入urllib库的urlopen函数 # from urllib.request import urlopen # # 发出请求,获取html # html = urlopen(" ...
- Element NavMenu动态生成导航菜单
为了演示方便,不从数据库获取了 { "data":[ { "id":125, " ...