GuozhongCrawler系列教程 (1) 三大PageDownloader
GuozhongCrawler QQ群 202568714
教程源代码下载地址:http://pan.baidu.com/s/1pJBmerL
GuozhongCrawler内置三大PageDownloader。各自是採用HttpClient作为内核下载的DefaultPageDownloader、採用HtmlUnitDriver作为内核下载WebDriverDownloader、採用ChromeDriver调用浏览器作为内核下载的ChromeDriverDownloader。
当中DefaultPageDownloader和WebDriverDownloader在实际开发中用的最好性能也是最好的。而ChromeDriverDownloader尽管性能不佳。可是ChromeDriverDownloader可以灵活调用浏览器抓取。
在调试过程中使用ChromeDriverDownloader可以看到爬虫真实的执行流程确实为开发增添了不少乐趣。
首先我们来看下怎样使用大三下载器。
以及它们各种什么特点。
一、DefaultPageDownloader
DefaultPageDownloader既然是採用HttpClient作为内核下载器。
那么他必须兼容全部httpClient应该有的功能。
样例我们以职友企业网抓取为样例。我们准备了阿里巴巴和淘宝网两个公司的主页URL。并通过CrawTaskBuilder注入到CrawlTask中。
prepareCrawlTask时指定使用DefaultPageDownloader作为下载器。
String alibaba = "http://www.jobui.com/company/281097/";
String taobao = "http://www.jobui.com/company/593687/";
CrawTaskBuilder builder = CrawlManager.getInstance()
.prepareCrawlTask("职友网爬虫", DefaultPageDownloader.class)
.useThread(2)//使用两个线程下载
.injectStartUrl(alibaba, PageCompanyDescript.class)
.injectStartUrl(taobao, PageCompanyDescript.class)
.usePageEncoding(PageEncoding.UTF8);
CrawlTask spider = builder.build();
CrawlManager.getInstance().start(spider);
PageCompanyDescript.java的实现我们如今临时仅仅输出解析出来的公司名称代码例如以下
public class PageCompanyDescript implements PageProcessor {
@Override
public PageScript getJavaScript() {
return null;
}
@Override
public Pattern getNormalContain() {
return null;
}
@Override
public void process(OkPage page, StartContext context,
List<BasicRequest> queue, List<Proccessable> objectContainer)
throws Exception {
Document doc = Jsoup.parse(page.getContent());
Element h1 = doc.select("h1[id=companyH1]").first();
if(h1 != null){
System.out.println("公司全称:"+h1.text());
}
}
@Override
public void processErrorPage(Page arg0, StartContext arg1)
throws Exception {
}
}
OK。如今測试代码就已经完毕。我们执行。

二、WebDriverDownloader
使用WebDriverDownloader事实上仅仅要把main方法中的prepareCrawlTask("职友网爬虫", DefaultPageDownloader.class)
改成prepareCrawlTask("职友网爬虫", WebDriverDownloader.class)就可以完毕WebDriverDownloader的设置。
为了体现差别我们在PageCompanyDescript中实现getJavaScript方法来运行一段js代码。getJavaScript实现例如以下:
@Override
public PageScript getJavaScript() {
return new PageScript() {
@Override
public void executeJS(HtmlUnitDriver driver) throws Exception {
WebElement element = driver.findElementById("companyH1");
driver.executeScript("arguments[0].innerHTML='WebDriverDownloader支持运行JavaScript';", element);
}
};
}
OK执行之后的结果例如以下图。

10:10:23,572到 10:10:32,056中间相差了9s的时间。这是由于webdriver的js引擎在jvm中运行确实过慢。但大规模抓取过程中还是建议採用抓包抓取的方式。
三、ChromeDriverDownloader
ChromeDriverDownloader和WebDriverDownloader功能上一样。
仅仅是下载会调用谷歌浏览器。用户须要安装谷歌浏览器和下载chromedriver。放在谷歌浏览器的安装文件夹。
我的文件夹是D:\program files (x86)\Chrome。
那么chromedriver的路径是D:\program files (x86)\Chrome\chromedriver.exe。
这里解释下ChromeDriver是Chromium team开发维护的。它是实现WebDriver有线协议的一个单独的服务。ChromeDriver通过chrome的自己主动代理框架控制浏览 器。ChromeDriver仅仅与12.0.712.0以上版本号的chrome浏览器兼容。
chromedriver下载地址:https://code.google.com/p/chromedriver/wiki/WheredAllTheDownloadsGo?
tm=2
之后我们改动main方法中的代码:
//设置chromedriver.exe路径
System.setProperty("webdriver.chrome.driver", "D:\\program files (x86)\\Chrome\\chromedriver.exe");
String alibaba = "http://www.jobui.com/company/281097/";
String taobao = "http://www.jobui.com/company/593687/";
CrawTaskBuilder builder = CrawlManager.getInstance()
.prepareCrawlTask("职友网爬虫", ChromeDriverDownloader.class)
.useThread(2)//使用两个线程下载
.injectStartUrl(alibaba, PageCompanyDescript.class)
.injectStartUrl(taobao, PageCompanyDescript.class)
.usePageEncoding(PageEncoding.UTF8);
CrawlTask spider = builder.build();
CrawlManager.getInstance().start(spider);
再次运行会弹出谷歌浏览器界面,我们能够看到爬虫抓取过程了。

控制台输出

可能你会注意到。
我们用了useThread(2)//使用两个线程下载。为什么没有出现两个谷歌浏览器同一时候抓。这里解释是由于我们注入种子URL的方式是使用injectStartUrl它会注入2个StartContext。而StartContext好比是一批种子URL的上下文。同一时间是不能同一时候使用的。
为此GuozhongCrawler提供了DynamicEntrance的概念实现多个种子URL同一时候共享一个StartContext的功能。想了解DynamicEntrance的话,请继续关注后期GuozhongCrawler系列教程。谢谢大家!
GuozhongCrawler QQ群 202568714
GuozhongCrawler系列教程 (1) 三大PageDownloader的更多相关文章
- GuozhongCrawler系列教程 (2) CrawTaskBuilder具体解释
GuozhongCrawler是分层架构.要高速学习CrawlTask独立的配置多少要了解框架的源码.所以CrawTaskBuilder提供要更加扁平且易于理解的的方式创建CrawTask 方法具体资 ...
- GuozhongCrawler系列教程 (4) StartContext具体解释
StartContext是注入时全部seed的上下文信息假设爬虫在抓取过程其中须要共享一些变量.那么可使用StartContext作为容器. 构造器具体资料 StartContext public S ...
- GuozhongCrawler系列教程 (5) TransactionRequest具体解释
为了实现和维护并发抓取的属性信息提供线程安全的事务请求.TransactionRequest是一个抽象类自己不能设置Processor,却须要实现 TransactionCallBack接口.Tran ...
- Java成神路上之设计模式系列教程之一
Java成神路上之设计模式系列教程之一 千锋-Feri 在Java工程师的日常中,是否遇到过如下问题: Java 中什么叫单例设计模式?请用Java 写出线程安全的单例模式? 什么是设计模式?你是否在 ...
- 从零开始学 Web 系列教程
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新…… github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http:/ ...
- JS面向对象系列教程 — 对象的基本操作
面向对象概述  面向对象(Object Oriented)简称OO,它是一种编程思维,用于指导我们如何应对各种复杂的开发场景. 这里说的对象(Object),意思就是事物,在面向对象的思维中,它将一 ...
- SpringBoot系列教程web篇之过滤器Filter使用指南
web三大组件之一Filter,可以说是很多小伙伴学习java web时最早接触的知识点了,然而学得早不代表就用得多.基本上,如果不是让你从0到1写一个web应用(或者说即便从0到1写一个web应用) ...
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数
上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...
随机推荐
- [CODEVS1914] 运输问题(最小费用最大流)
传送门 水题. 建图都不想说了 ——代码 #include <queue> #include <cstdio> #include <cstring> #includ ...
- [CODEVS1917] 深海机器人问题(最小费用最大流)
传送门 [问题分析] 最大费用最大流问题. [建模方法] 把网格中每个位置抽象成网络中一个节点,建立附加源S汇T. 1.对于每个顶点i,j为i东边或南边相邻的一个节点,连接节点i与节点j一条容量为1, ...
- 常用jar包下载地址汇总
<常用开发包下载地址汇总> 下载Jackson http://www.java2s.com/Code/Jar/j/Downloadjacksonjar.htm 下载Simple Loggi ...
- springboot中如果使用了@Autowired注入了bean,则这个类也要为spring bean,new出来注入的bean为null
https://blog.csdn.net/Mr_Runner/article/details/83684088 问题:new出来的实例中含有@Autowired注入时,注入的Bean为null: 解 ...
- PHP的图片处理类(缩放、加图片水印和剪裁)
<!--test.php文件内容--> <?php //包含这个类image.class.php include "image.class.php"; $img ...
- 【BZOJ4555】【TJOI2016】【HEOI2016】求和 (第二类斯特林数+NTT卷积)
Description 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: $$f(n)=\sum_{i=0}^n\sum_{j=0}^i S(i,j)\tim ...
- bzoj 1196 公路修建问题
bzoj 1196: [HNOI2006]公路修建问题 Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情 ...
- Yii CDbCriteria的常用方法总结
查看代码 打印 01 $criteria=new CDbCriteria; 02 $criteria->addCondition("id=1");//查询条件,即wher ...
- hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //最大流的灵活运用
3081 题意: n个女孩选择没有与自己吵过架的男孩有连边(自己的朋友也算,并查集处理),2分图,有些边,求有几种完美匹配(每次匹配每个点都不重复匹配) 我是建二分图后,每次增广一单位,(一次完美匹配 ...
- AC日记——【模板】最近公共祖先(LCA)洛谷 P3379
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...