WebMagic是一个简单灵活的Java爬虫框架。基于WebMagic,你能够快速开发出一个高效、易维护的爬虫。html
最新版:WebMagic-0.7.3java
<dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-core</artifactId> <version>0.7.3</version> </dependency> <dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-extension</artifactId> <version>0.7.3</version> </dependency>
上边是简单的介绍,相关使用参考做者编写的 中文文档git
下面是使用的相关拓展部分:github
Scheduler
是WebMagic
中进行 URL 管理的组件。通常来讲,Scheduler
包括两个做用:web
Scheduler的内部实现进行了重构,去重部分被单独抽象成了一个接口:DuplicateRemover
,从而能够为同一个Scheduler选择不一样的去重方式,以适应不一样的须要,目前提供了三种去重方式。redis
布隆过滤器的使用实例:算法
@Scheduled(initialDelay = 1000, fixedDelay = 60 * 1000 * 60 * 12) public void start() { Spider.create(new BdProcessor()) .addUrl(URL) .thread(10) // 设置布隆过滤器去重操做(默认使用HashSet来进行去重,占用内存较大;使用BloomFilter来进行去重,占用内存较小,可是可能漏抓页面) .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000000))) .addPipeline(dbPipeline) .run(); }
最多见的去重方案是生成文档的指纹门。例如对一篇文章进行 MD5 加密生成一个字符串,咱们能够认为这是文章的指纹码,再和其余的文章指纹码对比,一致则说明文章重复。api
可是这种方式是彻底一致则是重复的,若是文章只是多了几个标点符号,那仍旧被认为是重复的,这种方式并不合理。服务器
这种方式就是咱们以前对 url 进行去重的方式,使用在这里的话,也是对文章进行计算获得一个数,再进行对比,缺点和方法 1 是同样的,若是只有一点点不同,也会认为不重复,这种方式不合理。网络
KMP 算法是一种改进的字符串匹配算法。KMP 算法的关键是利用匹配失败后的信息,尽可能减小模式串与主串的匹配次数以达到快速匹配的目的。可以找到两个文章有哪些是一-样的,哪些不同。。
这种方式可以解决前面两个方式的“只要一点不同就是不重复”的问题。可是它的时空复杂度过高了,不适合大数据量的重复比对。
Google 的 simhash 算法产生的签名,能够知足上述要求。这个算法并不深奥,比较容易理解。这种算法也是目前 Google 搜索引擎所目前所使用的网页去重算法。
有些网站不容许爬虫进行数据爬取,由于会加大服务器的压力。其中一种最有效的方式是经过 ip+时间进行鉴别,由于正常人不可能短期开启太多的页面,发起太多的请求。
咱们使用的 WebMagic 能够很方便的设置爬取数据的时间(参考次日的的 3.1. 爬虫的配置、启动和终止)。可是这样会大大下降咱们 J 爬取数据的效率,若是不当心 ip 被禁了,会让咱们没法爬去数据,那么咱们就有必要使用代理服务器来爬取数据。
代理 L(英语:Proxy),也称网络代理,是一-种特殊的网络服务,容许一个网络终端(通常为客户端)经过这个服务与另外一个网络终端(通常为服务器)进行非直接的链接。
提供代理服务的电脑系统或其它类型的网络终端称为代理服务器(英文:Proxy. Server)。一个完整的代理请求过程为:客户端首先与代理服务器建立链接,接着根据代理服务器所使用的代理协议,请求对目标服务器建立链接、或者得到目标服务器的指定资源。
咱们就须要知道代理服务器在哪里(ip 和端口号)才可使用。网上有不少代理服务器的提供商,可是大可能是免费的很差用,付费的还行。推荐个免费的服务网站:
WebMagic的代理API ProxyProvider
。由于相对于 Site 的“配置”,ProxyProvider定位更可能是一个“组件”,因此代理再也不从Site设置,而是由HttpClientDownloader
设置。
HttpClientDownloader.setProxyProvider(ProxyProvider proxyProvider)
ProxyProvider
有一个默认实现:SimpleProxyProvider
。它是一个基于简单Round-Robin的、没有失败检查的ProxyProvider。能够配置任意个候选代理,每次会按顺序挑选一个代理使用。它适合用在本身搭建的比较稳定的代理的场景。
代理示例:
设置单一的普通HTTP代理为101.101.101.101的8888端口,并设置密码为"username","password"
HttpClientDownloader httpClientDownloader = new HttpClientDownloader(); httpClientDownloader.setProxyProvider(SimpleProxyProvider.from(new Proxy("101.101.101.101",8888,"username","password"))); spider.setDownloader(httpClientDownloader);
设置代理池,其中包括101.101.101.101和102.102.102.102两个IP,没有密码
HttpClientDownloader httpClientDownloader = new HttpClientDownloader(); httpClientDownloader.setProxyProvider(SimpleProxyProvider.from( new Proxy("101.101.101.101",8888) ,new Proxy("102.102.102.102",8888)));