- 1. WebMagic 概览
- 1.1 设计思想
- 1.2 总体架构
- 1.3 项目组成
- 2. 快速开始
- 2.1 使用Maven
- 2.2 不使用Maven
- 2.3 第一个爬虫项目
- 3. 下载和编译源码
- 3.1 下载源码
- 3.2 导入项目
- 3.3 编译和执行源码
- 4. 编写基本的爬虫
- 4.1 实现 PageProcessor
- 4.2 使用 Selectable 抽取元素
- 4.3 使用Pipeline保存结果
- 4.4 爬虫的配置、启动和终止
- 4.5 Jsoup与Xsoup
- 4.6 爬虫的监控
- 4.7 配置代理
- 4.8 处理非 HTTP GET 请求
- 5. 使用注解编写爬虫
- 5.1 编写Model类
- 5.2 TargetUrl与HelpUrl
- 5.3 使用ExtractBy进行抽取
- 5.4 在类上使用ExtractBy
- 5.5 结果的类型转换
- 5.6 一个完整的流程
- 5.7 AfterExtractor
- 6. 组件的使用和定制
- 6.1 使用和定制 Pipeline
- 6.2 使用和定制 Scheduler
- 6.3 使用和定制 Downloader
- 附录:实例分析
- 列表 + 详情的基本页面组合
- 抓取前端渲染的页面
4.1 实现 PageProcessor
这部分我们直接通过 GithubRepoPageProcessor
这个例子来介绍 PageProcessor
的编写方式。我将 PageProcessor 的定制分为三个部分,分别是爬虫的配置、页面元素的抽取和链接的发现。
public class GithubRepoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);
@Override
// process 是定制爬虫逻辑的核心接口,在这里编写抽取逻辑
public void process(Page page) {
// 部分二:定义如何抽取页面信息,并保存下来
page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString());
page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString());
if (page.getResultItems().get("name") == null) {
//skip this page
page.setSkip(true);
}
page.putField("readme", page.getHtml().xpath("//div[@id='readme']/tidyText()"));
// 部分三:从页面发现后续的 url 地址来抓取
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/[\\w\\-]+/[\\w\\-]+)").all());
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) {
Spider.create(new GithubRepoPageProcessor())
//从"https://github.com/code4craft"开始抓
.addUrl("https://github.com/code4craft")
//开启 5 个线程抓取
.thread(5)
//启动爬虫
.run();
}
}
4.1.1 爬虫的配置
第一部分关于爬虫的配置,包括编码、抓取间隔、超时时间、重试次数等,也包括一些模拟的参数,例如 User Agent、cookie,以及代理的设置,我们会在第 5 章-“爬虫的配置”里进行介绍。在这里我们先简单设置一下:重试次数为 3 次,抓取间隔为一秒。
4.1.2 页面元素的抽取
第二部分是爬虫的核心部分:对于下载到的 Html 页面,你如何从中抽取到你想要的信息?WebMagic 里主要使用了三种抽取技术:XPath、正则表达式和 CSS 选择器。另外,对于 JSON 格式的内容,可使用 JsonPath 进行解析。
XPath
XPath 本来是用于 XML 中获取元素的一种查询语言,但是用于 Html 也是比较方便的。例如:
page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()")
这段代码使用了 XPath,它的意思是 查找所有 class 属性为 entry-title public
的 h1 元素,并找到他的 strong 子节点的 a 子节点,并提取 a 节点的文本信息。
CSS 选择器
CSS 选择器是与 XPath 类似的语言。如果大家做过前端开发,肯定知道$('h1.entry-title') 这种写法的含义。客观的说,它比 XPath 写起来要简单一些,但是如果写复杂一点的抽取规则,就相对要麻烦一点。
正则表达式
正则表达式则是一种通用的文本抽取语言。
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());
这段代码就用到了正则表达式,它表示匹配所有"https://github.com/code4craft/webmagic"这样的链接。
JsonPath
JsonPath 是于 XPath 很类似的一个语言,它用于从 Json 中快速定位一条内容。WebMagic 中使用的 JsonPath 格式可以参考这里: https://code.google.com/p/json-path/
4.1.3 链接的发现
有了处理页面的逻辑,我们的爬虫就接近完工了!
但是现在还有一个问题:一个站点的页面是很多的,一开始我们不可能全部列举出来,于是如何发现后续的链接,是一个爬虫不可缺少的一部分。
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());
这段代码的分为两部分, page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all()
用于获取所有满足 "(https:/ /github\.com/\w+/\w+)"
这个正则表达式的链接, page.addTargetRequests()
则将这些链接加入到待抓取的队列中去。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论