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 爬虫技术的更多相关文章

  1. 总结整理 -- 爬虫技术(C#版)

    爬虫技术学习总结 爬虫技术 -- 基础学习(一)HTML规范化(附特殊字符编码表) 爬虫技术 -- 基本学习(二)爬虫基本认知 爬虫技术 -- 基础学习(三)理解URL和URI的联系与区别 爬虫技术 ...

  2. 爬虫技术 -- 基础学习(四)HtmlParser基本认识

    利用爬虫技术获取网页源代码后,针对网页抽取出它的特定文本内容,利用正则表达式和抽取工具,能够更好地抽取这些内容. 下面介绍一种抽取工具 -- HtmlParser HtmlParser是一个用来解析H ...

  3. 爬虫技术浅析 | WooYun知识库

    爬虫技术浅析 | WooYun知识库 爬虫技术浅析 好房通ERP | 房产中介软件最高水准领导者 undefined

  4. 爬虫技术实战 | WooYun知识库

    爬虫技术实战 | WooYun知识库 爬虫技术实战 大数据分析与机器学习领域Python兵器谱-大数据邦-微头条(wtoutiao.com) 大数据分析与机器学习领域Python兵器谱

  5. 爬虫技术浅析 | z7y Blog

    爬虫技术浅析 | z7y Blog 爬虫技术浅析

  6. .net 爬虫技术

    关于爬虫 从搜索引擎开始,爬虫应该就出现了,爬的对象当然也就是网页URL,在很长一段时间内,爬虫所做的事情就是分析URL.下载WebServer返回的HTML.分析HTML内容.构建HTTP请求的模拟 ...

  7. 使用webcollector爬虫技术获取网易云音乐全部歌曲

    最近在知乎上看到一个话题,说使用爬虫技术获取网易云音乐上的歌曲,甚至还包括付费的歌曲,哥瞬间心动了,这年头,好听的流行音乐或者经典老歌都开始收费了,只能听不能下载,着实很郁闷,现在机会来了,于是开始研 ...

  8. 使用htmlparse爬虫技术爬取电影网页的全部下载链接

    昨天,我们利用webcollector爬虫技术爬取了网易云音乐17万多首歌曲,而且还包括付费的在内,如果时间允许的话,可以获取更多的音乐下来,当然,也有小伙伴留言说这样会降低国人的知识产权保护意识,诚 ...

  9. 利用python的爬虫技术爬去糗事百科的段子

    初次学习爬虫技术,在知乎上看了如何爬去糗事百科的段子,于是打算自己也做一个. 实现目标:1,爬取到糗事百科的段子 2,实现每次爬去一个段子,每按一次回车爬取到下一页 技术实现:基于python的实现, ...

随机推荐

  1. uwp 之语音识别

    xml code ---------------------------------------------- <Page x:Class="MyApp.MainPage" ...

  2. 刷题-力扣-213. 打家劫舍 II

    213. 打家劫舍 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/house-robber-ii/ 著作权归领扣网络所有.商业 ...

  3. C# ArrayPool 源码解读之 byte[] 池化

    一:背景 1. 讲故事最近在分析一个 dump 的过程中发现其在 gen2 和 LOH 上有不少size较大的free,仔细看了下,这些free生前大多都是模板引擎生成的html片段的byte[]数组 ...

  4. ros-kinetic install error: sudo rosdep init ImportError: No module named 'rosdep2'

    refer to: https://blog.csdn.net/yueyueniaolzp/article/details/85070093 方法一 将Ubuntu默认python版本设置为2.7 方 ...

  5. VSCode中相对路径设置问题

    使用的版本 对于import xxx操作,相对路径为sys.path 对于open("test.txt",'r')文件打开操作,相对路径为os.getcwd() 对于termina ...

  6. linux-解决/usr/bin/which: no ssh-copy-id in 和ssh: Could not resolve hostname问题

    使用yum install openssh-clients  安装命令 有的系统没有此命令 有的系统缺省 就包含这一条命令! 但是我的测试机没有发现此命令 只能这样安装! 这时有报错了 1 2 [ro ...

  7. Why TypeScript?

    本文经作者授权,翻译总结自 TypeScript Team 的成员 orta 的个人博客 <Understanding TypeScript's Popularity>. 原作者: ort ...

  8. java版gRPC实战之一:用proto生成代码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. session案例之验证码

    一.需求分析 其中,一张图片就是一个单独的请求: 一个验证验证码的Servlet,还有一个验证用户名和密码的Servlet,两次都可能有错误信息返回到前端页面,所以前面页面要从request域中获取返 ...

  10. FileWriter文件文件字符输出流写入存储数据

    1.FileWriter文件字符输出流-写入-存储数据 其中,流关闭之后再调用会报IOException; 其中,与文件字符输入流-写出-读取数据 和 字节输出流-写入-存储数据 不同的是,要先flu ...