java之网络爬虫介绍(非原创)

文章大纲

1、网络爬虫基本介绍
2、java常见爬虫框架介绍
3、WebCollector实战
4、项目源码下载
5、参考文章javascript

 

1、网络爬虫基本介绍

1. 什么是网络爬虫

  网络爬虫(又被称为网页蜘蛛,网络机器人,在社区中间,更常常的称为网页追逐者),是一种按照必定的规则,自动地抓取万维网信息的程序或者脚本。另一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。css

2. 常见问题介绍

爬虫能够爬取ajax信息么?
  网页上有一些异步加载的数据,爬取这些数据有两种方法:使用模拟浏览器(问题1中描述过了),或者分析ajax的http请求,本身生成ajax请求的url,获取返回的数据。若是是本身生成ajax请求,使用开源爬虫的意义在哪里?实际上是要用开源爬虫的线程池和URL管理功能(好比断点爬取)。
  若是我已经能够生成我所须要的ajax请求(列表),如何用这些爬虫来对这些请求进行爬取?
  爬虫每每都是设计成广度遍历或者深度遍历的模式,去遍历静态或者动态页面。爬取ajax信息属于deep web(深网)的范畴,虽然大多数爬虫都不直接支持。可是也能够经过一些方法来完成。好比WebCollector使用广度遍从来遍历网站。爬虫的第一轮爬取就是爬取种子集合(seeds)中的全部url。简单来讲,就是将生成的ajax请求做为种子,放入爬虫。用爬虫对这些种子,进行深度为1的广度遍历(默认就是广度遍历)。html

爬虫支持多线程么、爬虫能用代理么、爬虫会爬取重复数据么、爬虫能爬取JS生成的信息么?
  能不能爬js生成的信息和爬虫自己没有太大关系。爬虫主要是负责遍历网站和下载页面。爬js生成的信息和网页信息抽取模块有关,每每须要经过模拟浏览器(htmlunit,selenium)来完成。这些模拟浏览器,每每须要耗费不少的时间来处理一个页面。因此一种策略就是,使用这些爬虫来遍历网站,遇到须要解析的页面,就将网页的相关信息提交给模拟浏览器,来完成JS生成信息的抽取。java

爬虫怎么保存网页的信息?
  有一些爬虫,自带一个模块负责持久化。好比webmagic,有一个模块叫pipeline。经过简单地配置,能够将爬虫抽取到的信息,持久化到文件、数据库等。还有一些爬虫,并无直接给用户提供数据持久化的模块。好比crawler4j和webcollector。让用户本身在网页处理模块中添加提交数据库的操做。至于使用pipeline这种模块好很差,就和操做数据库使用ORM好很差这个问题相似,取决于你的业务。linux

爬虫怎么爬取要登录的网站?
  这些开源爬虫都支持在爬取时指定cookies,模拟登录主要是靠cookies。至于cookies怎么获取,不是爬虫管的事情。你能够手动获取、用http请求模拟登录或者用模拟浏览器自动登录获取cookie。git

爬虫怎么抽取网页的信息?
  开源爬虫通常都会集成网页抽取工具。主要支持两种规范:CSS SELECTOR和XPATH。至于哪一个好,这里不评价。程序员

明明代码写对了,爬不到数据,是否是爬虫有问题,换个爬虫能解决么?
  若是代码写对了,又爬不到数据,换其余爬虫也是同样爬不到。遇到这种状况,要么是网站把你封了,要么是你爬的数据是javascript生成的。爬不到数据经过换爬虫是不能解决的。github

爬虫速度怎么样?
  单机开源爬虫的速度,基本均可以讲本机的网速用到极限。爬虫的速度慢,每每是由于用户把线程数开少了、网速慢,或者在数据持久化时,和数据库的交互速度慢。而这些东西,每每都是用户的机器和二次开发的代码决定的。web

爬虫被网站封了怎么办?
  爬虫被网站封了,通常用多代理(随机代理)就能够解决。可是这些开源爬虫通常没有直接支持随机代理ip的切换。ajax

2、java常见爬虫框架介绍

1. Apache Nutch

(1)官方网站:http://nutch.apache.org/
(2)是否支持分布式:是
(3)可扩展性:中。Apache Nutch并非一个可扩展性很强的爬虫,它是一个专门为搜索引擎定制的网络爬虫,虽然Apache Nutch具备一套强大的插件机制,但经过定制插件并不能修改爬虫的遍历算法、去重算法和爬取流程。
(4)适用性:Apache Nutch是为搜索引擎定制的爬虫,具备一套适合搜索引擎的URL维护机制(包括URL去重、网页更新等),但这套机制并不适合目前大多数的精抽取业务(即结构化数据采集)。
(5)上手难易度:难。须要使用者熟悉网络爬虫原理、hadoop开发基础及linux shell,且须要熟悉Apache Ant

2. WebCollector

(1)官方网站:https://github.com/CrawlScript/WebCollector
(2)可扩展性:强
(3)适用性:WebCollector适用于精抽取业务。
(4)上手难易度:简单

3. WebMagic

(1)官方网站:http://git.oschina.net/flashsword20/webmagic
(2)是否支持分布式:否
(3)可扩展性:强
(4)适用性:WebMagic适用于精抽取业务。
(5)上手难易度:简单。

4. Crawler4j

(1)官方网站:https://github.com/yasserg/crawler4j
(2) 是否支持分布式:否
(3)可扩展性:低。Crawler4j其实是一个单机版的垂直爬虫,其遍历算法是一种相似泛爬的算法,虽然能够添加一些限制,但仍不能知足目前大部分的精抽取业务。另外,Crawler4j并无提供定制http请求的接口,所以Crawler4j并不适用于须要定制http请求的爬取业务(例如模拟登录、多代理切换)。
(4)上手难易度:简单

3、WebCollector实战

1. WebCollector与传统网络爬虫的区别

  传统的网络爬虫倾向于整站下载,目的是将网站内容原样下载到本地,数据的最小单元是单个网页或文件。而WebCollector能够经过设置爬取策略进行定向采集,并能够抽取网页中的结构化信息。

2. WebCollector与HttpClient、Jsoup的区别

  WebCollector是爬虫框架,HttpClient是Http请求组件,Jsoup是网页解析器(内置了Http请求功能)。
一些程序员在单线程中经过迭代或递归的方法调用HttpClient和Jsoup进行数据采集,这样虽然也能够完成任务,但存在两个较大的问题:
(1)单线程速度慢,多线程爬虫的速度远超单线程爬虫。
(2)须要本身编写任务维护机制。这套机制里面包括了URL去重、断点爬取(即异常中断处理)等功能。
WebCollector框架自带了多线程和URL维护,用户在编写爬虫时无需考虑线程池、URL去重和断点爬取的问题。

3. WebCollector可以处理的量级

  WebCollector目前有单机版和Hadoop版(WebCollector-Hadoop),单机版可以处理千万级别的URL,对于大部分的精数据采集任务,这已经足够了。WebCollector-Hadoop可以处理的量级高于单机版,具体数量取决于集群的规模。

4. WebCollector的遍历

  WebCollector采用一种粗略的广度遍历,但这里的遍历与网站的拓扑树结构没有任何关系,用户不须要在乎遍历的方式。
  网络爬虫会在访问页面时,从页面中探索新的URL,继续爬取。WebCollector为探索新URL提供了两种机制,自动解析和手动解析。

5. 代码实战

maven引入依赖

<dependencies> <dependency> <groupId>cn.edu.hfut.dmic.webcollector</groupId> <artifactId>WebCollector</artifactId> <version>2.73-alpha</version> </dependency> </dependencies> 

自动解析

import cn.edu.hfut.dmic.webcollector.model.CrawlDatums; import cn.edu.hfut.dmic.webcollector.model.Page; import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler; public class AutoNewsCrawler extends BreadthCrawler { public AutoNewsCrawler(String crawlPath, boolean autoParse) { super(crawlPath, autoParse); this.addSeed("http://news.hfut.edu.cn/list-1-1.html");//种子页面,起始页面 //正则规则设置 寻找符合http://news.hfut.edu.cn/show-xxxxxxhtml的url this.addRegex("http://news.hfut.edu.cn/show-.*html"); this.addRegex("-.*\\.(jpg|png|gif).*"); //不要爬取包含 #的URL this.addRegex("-.*#.*"); setThreads(50);//线程数 getConf().setTopN(100);//设置每次迭代中爬取数量的上限 //设置是否为断点爬取,若是设置为false,任务启动前会清空历史数据。 //若是设置为true,会在已有crawlPath(构造函数的第一个参数)的基础上继 //续爬取。对于耗时较长的任务,极可能须要中途中断爬虫,也有可能遇到 //死机、断电等异常状况,使用断点爬取模式,能够保证爬虫不受这些因素 //的影响,爬虫能够在人为中断、死机、断电等状况出现后,继续之前的任务 //进行爬取。断点爬取默认为false*/ // setResumable(true); } /* visit函数定制访问每一个页面时所需进行的操做 */ @Override public void visit(Page page, CrawlDatums next) { String url = page.url(); //若是页面地址如何咱们要求 if (page.matchUrl("http://news.hfut.edu.cn/show-.*html")) { String title = page.select("div[id=Article]>h2").first().text();//获取url标题 String content = page.selectText("div#artibody"); System.out.println("URL:\n" + url);//地址 System.out.println("title:\n" + title);//标题 System.out.println("content:\n" + content);//内容 /*若是你想添加新的爬取任务,能够向next中添加爬取任务, 这就是上文中提到的手动解析*/ /*WebCollector会自动去掉重复的任务(经过任务的key,默认是URL), 所以在编写爬虫时不须要考虑去重问题,加入重复的URL不会致使重复爬取*/ /*若是autoParse是true(构造函数的第二个参数),爬虫会自动抽取网页中符合正则规则的URL, 做为后续任务,固然,爬虫会去掉重复的URL,不会爬取历史中爬取过的URL。 autoParse为true即开启自动解析机制*/ //next.add("http://xxxxxx.com"); } } public static void main(String[] args) throws Exception { AutoNewsCrawler crawler = new AutoNewsCrawler("crawl", true); crawler.start(4);//启动爬虫 } } 

运行接入以下所示:

 

手动解析

import cn.edu.hfut.dmic.webcollector.model.CrawlDatums; import cn.edu.hfut.dmic.webcollector.model.Page; import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler; public class ManualNewsCrawler extends BreadthCrawler { public ManualNewsCrawler(String crawlPath, boolean autoParse) { super(crawlPath, autoParse); /*add 10 start pages and set their type to "list" "list" is not a reserved word, you can use other string instead */ for(int i = 1; i <= 10; i++) { this.addSeed("http://news.hfut.edu.cn/list-1-" + i + ".html", "list");//种子页面,起始页面 } setThreads(50);//线程数 getConf().setTopN(100);//设置每次迭代中爬取数量的上限 //设置是否为断点爬取,若是设置为false,任务启动前会清空历史数据。 //若是设置为true,会在已有crawlPath(构造函数的第一个参数)的基础上继 //续爬取。对于耗时较长的任务,极可能须要中途中断爬虫,也有可能遇到 //死机、断电等异常状况,使用断点爬取模式,能够保证爬虫不受这些因素 //的影响,爬虫能够在人为中断、死机、断电等状况出现后,继续之前的任务 //进行爬取。断点爬取默认为false*/ // setResumable(true); } /* visit函数定制访问每一个页面时所需进行的操做 * */ @Override public void visit(Page page, CrawlDatums next) { String url = page.url(); if (page.matchType("list")) { next.add(page.links("div[class=' col-lg-8 '] li>a")).type("content"); }else if(page.matchType("content")) { /*if type is "content"*/ /*extract title and content of news by css selector*/ String title = page.select("div[id=Article]>h2").first().text(); String content = page.selectText("div#artibody", 0); //read title_prefix and content_length_limit from configuration title = getConf().getString("title_prefix") + title; content = content.substring(0, getConf().getInteger("content_length_limit")); System.out.println("URL:\n" + url); System.out.println("title:\n" + title); System.out.println("content:\n" + content); } } public static void main(String[] args) throws Exception { ManualNewsCrawler crawler = new ManualNewsCrawler("crawl", false); crawler.getConf().setExecuteInterval(5000); crawler.getConf().set("title_prefix","PREFIX_"); crawler.getConf().set("content_length_limit", 20); crawler.start(4);//启动爬虫 } } 

运行结果以下图所示:

 

4、项目源码下载

连接:https://pan.baidu.com/s/10Ze9xloOpVqmlBOj97XNaQ
提取码:ig45

5、参考文章

    1. https://blog.51cto.com/14059916/2317860
    2. https://blog.csdn.net/acmdream/article/details/70159898
    3. https://blog.csdn.net/lhz15527200472/article/details/77868996
相关文章
相关标签/搜索