最近由于有爬一些招聘网站的招聘信息的须要,而我以前也只是知道有“网络爬虫”这个神奇的名词,具体是什么、用什么实现、什么原理、如何实现比较好都不清楚,所以最近大体研究了一下,固然,研究的并非很深刻,毕竟一个高大上的知识即便站在巨人的肩膀上,也不能两三天就融会贯通。在这里先作一个技术储备吧,具体的疑难知识点、细节等之后一点一点的完善,若是如今不趁热打铁,之后再想起来恐怕就没印象了,那么以个人懒惰的性格估计就要抛弃对它的爱情了。废话很少说,让咱们开始在知识的海洋里遨游吧。哎,等等,说到这我忽然想到昨天新记的一首诗感受挺好,给你们分享一下,缓解一下气氛,再给你们讲爬虫吧:html
君生我未生,我生君已老 君恨我生迟,我恨君生早
君生我未生,我生君已老 恨不生同时,日日与君好
我生君未生,君生我已老 我离君天涯,君隔我海角
我生君未生,君生我已老 化蝶去寻花,夜夜栖芳草 java
是一种按照必定的规则,自动地抓取万维网信息的程序或者脚本。git
简单易理解,管理方便。github
Downloader负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient做为下载工具。web
PageProcessor负责解析页面,抽取有用信息,以及发现新的连接。WebMagic使用Jsoup做为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。正则表达式
在这四个组件中,PageProcessor
对于每一个站点每一个页面都不同,是须要使用者定制的部分。数据库
Scheduler负责管理待抓取的URL,以及一些去重的工做。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。apache
除非项目有一些特殊的分布式需求,不然无需本身定制Scheduler。浏览器
Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。网络
Pipeline
定义告终果保存的方式,若是你要保存到指定数据库,则须要编写对应的Pipeline。对于一类需求通常只需编写一个Pipeline
。
依赖:
1 <dependency> 2 <groupId>us.codecraft</groupId> 3 <artifactId>webmagic-core</artifactId> 4 <version>0.6.1</version> 5 </dependency> 6 <dependency> 7 <groupId>us.codecraft</groupId> 8 <artifactId>webmagic-extension</artifactId> 9 <version>0.6.1</version> 10 </dependency>
简单代码:
1 import us.codecraft.webmagic.Page; 2 import us.codecraft.webmagic.Site; 3 import us.codecraft.webmagic.Spider; 4 import us.codecraft.webmagic.processor.PageProcessor; 5 6 public class GithubRepoPageProcessor implements PageProcessor { 7 8 private Site site = Site.me().setRetryTimes(3).setSleepTime(100); 9 10 @Override 11 public void process(Page page) { 12 page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all()); 13 page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString()); 14 page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString()); 15 if (page.getResultItems().get("name")==null){ 16 //skip this page 17 page.setSkip(true); 18 } 19 page.putField("readme", page.getHtml().xpath("//div[@id='readme']/tidyText()")); 20 } 21 22 @Override 23 public Site getSite() { 24 return site; 25 } 26 27 public static void main(String[] args) { 28 Spider.create(new GithubRepoPageProcessor()).addUrl("https://github.com/code4craft").thread(5).run(); 29 }
若是仔细分析这段代码的逻辑,将其弄明白了,那么对于一个简单的爬虫项目,你就能够本身写了。
addUrl
是定义从哪个页面开始爬取;
addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());是指定抓取html页面的符合此正则表达式的全部连接url;
page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString是指定抓取h1标签下的class属性值为
entry-title public的子标
签strong下的a标签下的文本内容;
tidyText()全部的直接和间接文本子节点,并将一些标签替换为换行,使纯文本显示更整洁。固然这也就要求你们也要对正则表达式熟悉了。本文用的是xsoup,Xsoup是基于
Jsoup开发的一款XPath 解析器,以前WebMagic使用的解析器是HtmlCleaner,使用过程存在一些问题。主要问题是XPath出错定位不许确,而且其不太合理的代码结构进行定制。而Xsoup更加符 合爬虫开发的需 要。使人欣喜的是,通过测试,Xsoup的性能比HtmlCleaner要快一倍以上。 基于
,
也难以,
也难以,
经过注解将值赋给model属性的实体类:
1 @TargetUrl("https://github.com/\\w+/\\w+") 2 @HelpUrl("https://github.com/\\w+") 3 public class GithubRepo { 4 5 @ExtractBy(value = "//h1[@class='entry-title public']/strong/a/text()", notNull = true) 6 private String name; 7 8 @ExtractByUrl("https://github\\.com/(\\w+)/.*") 9 private String author; 10 11 @ExtractBy("//div[@id='readme']/tidyText()") 12 private String readme; 13 }
是一个很是有效的爬虫开发模式,TargetUrl是咱们最终要抓取的URL,最终想要的数据都来自这里;而HelpUrl则是为了发现这个最终URL,咱们须要访问的页面。几乎全部垂直爬虫的需求,均可以归结为对这两类URL的处理:
提示:
HelpUrl/TargetUrl
模拟浏览器请求:
1 public VideoSpider(String url, String proxyStr) { 2 this.client_url = url; 3 String[] tmp = proxyStr.split(":"); 4 HttpHost proxy = new HttpHost(tmp[1].substring(2), Integer.parseInt(tmp[2]), tmp[0]); 5 Site site = Site.me().setRetryTimes(3).setHttpProxy(proxy).setSleepTime(100).setTimeOut(10 * 1000).setCharset("UTF-8") 6 .setUserAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"); 7 8 GPHttpClientDownloader downloader = new GPHttpClientDownloader(); 9 Request request = new Request(this.client_url); 10 11 this.setCookie(request, site, downloader); 12 this.setParameters(request, site, downloader); 13 }
中setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"),jobInfoDaoPipeline, LieTouJobInfo.class)
是模拟火狐、苹果、谷歌等浏览器进行请求将经过实体类LieTouJobInfo来抓取指定的内容并经过数据库访问层jobInfoDaoPipeline将相关属性存入数据库。
简单的爬虫用以上代码基本就能够实现,可是咱们要知道,要想真正爬取本身想要的内容,还有一段很长的落要走。由于咱们在抓取数据的时候要考虑到去重、动态页面的产生、快速的更新频率、巨大的数据量等等的问题。针对这些问题咱们该怎么作才能有效简单的去解决,这是
一个特别值得探讨的问题。就先写到这吧,若是我研究的有进展了,足以在公司项目中稳定投入使用了,再来完善吧。
最新版:WebMagic-0.6.1
Maven依赖:
<dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-core</artifactId> <version>0.6.1</version> </dependency> <dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-extension</artifactId> <version>0.6.1</version> </dependency>