网络爬虫基本原理以及Jsoup基本使用方法

1.网络爬虫基本原理

       网络爬虫是捜索引擎抓取系统的重要组成部分。爬虫的主要目的是将互联网上的网页下载到本地造成一个或联网内容的镜像备份。这篇博客主要对爬虫以及抓取系统进行一个简单的概述。java

1、网络爬虫的基本结构及工做流程

    一个通用的网络爬虫的框架如图所示:算法


网络爬虫的基本工做流程以下:api

    1.首先选取一部分精心挑选的种子URL;服务器

    2.将这些URL放入待抓取URL队列;网络

    3.从待抓取URL队列中取出待抓取在URL,解析DNS,而且获得主机的ip,并将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL放进已抓取URL队列。框架

    4.分析已抓取URL队列中的URL,分析其中的其余URL,而且将URL放入待抓取URL队列,从而进入下一个循环。分布式

2、从爬虫的角度对互联网进行划分

    对应的,能够将互联网的全部页面分为五个部分:网站


1.已下载未过时网页
搜索引擎

    2.已下载已过时网页:抓取到的网页其实是互联网内容的一个镜像与备份,互联网是动态变化的,一部分互联网上的内容已经发生了变化,这时,这部分抓取到的网页就已通过期了。url

    3.待下载网页:也就是待抓取URL队列中的那些页面

    4.可知网页:尚未抓取下来,也没有在待抓取URL队列中,可是能够经过对已抓取页面或者待抓取URL对应页面进行分析获取到的URL,认为是可知网页。

    5.还有一部分网页,爬虫是没法直接抓取下载的。称为不可知网页。

3、抓取策略

    在爬虫系统中,待抓取URL队列是很重要的一部分。待抓取URL队列中的URL以什么样的顺序排列也是一个很重要的问题,由于这涉及到先抓取那个页面,后抓取哪一个页面。而决定这些URL排列顺序的方法,叫作抓取策略。下面重点介绍几种常见的抓取策略:

    1.深度优先遍历策略

深度优先遍历策略是指网络爬虫会从起始页开始,一个连接一个连接跟踪下去,处理完这条线路以后再转入下一个起始页,继续跟踪连接。咱们如下面的图为例:



遍历的路径:A-F-G  E-H-I B C D

    2.宽度优先遍历策略

    宽度优先遍历策略的基本思路是,将新下载网页中发现的连接直接插入待抓取URL队列的末尾。也就是指网络爬虫会先抓取起始网页中连接的全部网页,而后再选择其中的一个连接网页,继续抓取在此网页中连接的全部网页。仍是以上面的图为例:

    遍历路径:A-B-C-D-E-F G H I

    3.反向连接数策略

    反向连接数是指一个网页被其余网页连接指向的数量。反向连接数表示的是一个网页的内容受到其余人的推荐的程度。所以,不少时候搜索引擎的抓取系统会使用这个指标来评价网页的重要程度,从而决定不一样网页的抓取前后顺序。

    在真实的网络环境中,因为广告连接、做弊连接的存在,反向连接数不能彻底等他我那个也的重要程度。所以,搜索引擎每每考虑一些可靠的反向连接数。

    4.Partial PageRank策略

    Partial PageRank算法借鉴了PageRank算法的思想:对于已经下载的网页,连同待抓取URL队列中的URL,造成网页集合,计算每一个页面的PageRank值,计算完以后,将待抓取URL队列中的URL按照PageRank值的大小排列,并按照该顺序抓取页面。

    若是每次抓取一个页面,就从新计算PageRank值,一种折中方案是:每抓取K个页面后,从新计算一次PageRank值。可是这种状况还会有一个问题:对于已经下载下来的页面中分析出的连接,也就是咱们以前提到的未知网页那一部分,暂时是没有PageRank值的。为了解决这个问题,会给这些页面一个临时的PageRank值:将这个网页全部入链传递进来的PageRank值进行汇总,这样就造成了该未知页面的PageRank值,从而参与排序。下面举例说明:

    5.OPIC策略策略

    该算法实际上也是对页面进行一个重要性打分。在算法开始前,给全部页面一个相同的初始现金(cash)。当下载了某个页面P以后,将P的现金分摊给全部从P中分析出的连接,而且将P的现金清空。对于待抓取URL队列中的全部页面按照现金数进行排序。

    6.大站优先策略

    对于待抓取URL队列中的全部网页,根据所属的网站进行分类。对于待下载页面数多的网站,优先下载。这个策略也所以叫作大站优先策略。


4、更新策略

    互联网是实时变化的,具备很强的动态性。网页更新策略主要是决定什么时候更新以前已经下载过的页面。常见的更新策略又如下三种:

    1.历史参考策略

    顾名思义,根据页面以往的历史更新数据,预测该页面将来什么时候会发生变化。通常来讲,是经过泊松过程进行建模进行预测。

    2.用户体验策略
    尽管搜索引擎针对于某个查询条件可以返回数量巨大的结果,可是用户每每只关注前几页结果。所以,抓取系统能够优先更新那些现实在查询结果前几页中的网页,然后再更新那些后面的网页。这种更新策略也是须要用到历史信息的。用户体验策略保留网页的多个历史版本,而且根据过去每次内容变化对搜索质量的影响,得出一个平均值,用这个值做为决定什么时候从新抓取的依据。
    3.聚类抽样策略

    前面提到的两种更新策略都有一个前提:须要网页的历史信息。这样就存在两个问题:第一,系统要是为每一个系统保存多个版本的历史信息,无疑增长了不少的系统负担;第二,要是新的网页彻底没有历史信息,就没法肯定更新策略。

    这种策略认为,网页具备不少属性,相似属性的网页,能够认为其更新频率也是相似的。要计算某一个类别网页的更新频率,只须要对这一类网页抽样,以他们的更新周期做为整个类别的更新周期。基本思路如图:


5、分布式抓取系统结构

    通常来讲,抓取系统须要面对的是整个互联网上数以亿计的网页。单个抓取程序不可能完成这样的任务。每每须要多个抓取程序一块儿来处理。通常来讲抓取系统每每是一个分布式的三层结构。如图所示:


最下一层是分布在不一样地理位置的数据中心,在每一个数据中内心有若干台抓取服务器,而每台抓取服务器上可能部署了若干套爬虫程序。这就构成了一个基本的分布式抓取系统。

    对于一个数据中心内的不一样抓去服务器,协同工做的方式有几种:

    1.主从式(Master-Slave)

    主从式基本结构如图所示:


对于主从式而言,有一台专门的Master服务器来维护待抓取URL队列,它负责每次将URL分发到不一样的Slave服务器,而Slave服务器则负责实际的网页下载工做。Master服务器除了维护待抓取URL队列以及分发URL以外,还要负责调解各个Slave服务器的负载状况。以避免某些Slave服务器过于悠闲或者劳累。

    这种模式下,Master每每容易成为系统瓶颈。

    2.对等式(Peer to Peer)

    对等式的基本结构如图所示:

在这种模式下,全部的抓取服务器在分工上没有不一样。每一台抓取服务器均可以从待抓取在URL队列中获取URL,而后对该URL的主域名的hash值H,而后计算H mod m(其中m是服务器的数量,以上图为例,m为3),计算获得的数就是处理该URL的主机编号。

    举例:假设对于URL www.baidu.com,计算器hash值H=8,m=3,则H mod m=2,所以由编号为2的服务器进行该连接的抓取。假设这时候是0号服务器拿到这个URL,那么它将该URL转给服务器2,由服务器2进行抓取。

    这种模式有一个问题,当有一台服务器死机或者添加新的服务器,那么全部URL的哈希求余的结果就都要变化。也就是说,这种方式的扩展性不佳。针对这种状况,又有一种改进方案被提出来。这种改进的方案是一致性哈希法来肯定服务器分工。其基本结构如图所示:

一致性哈希将URL的主域名进行哈希运算,映射为一个范围在0-2

一致性哈希将URL的主域名进行哈希运算,映射为一个范围在0-232之间的某个数。而将这个范围平均的分配给m台服务器,根据URL主域名哈希运算的值所处的范围判断是哪台服务器来进行抓取。

    若是某一台服务器出现问题,那么本该由该服务器负责的网页则按照顺时针顺延,由下一台服务器进行抓取。这样的话,及时某台服务器出现问题,也不会影响其余的工做。


2.Jsoup基本使用

       jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套很是省力的API,可经过DOM,CSS以及相似于jQuery的操做方法来取出和操做数据。

jsoup api地址:http://www.open-open.com/jsoup/ 

参考代码:

/**
 * 获取网页内容,使用代理访问
 * 设定取网页内容延时设置为20s(默认的Socket的延时比较短,而有些网站的响应速度比较慢,因此会发生超时的状况)
 * @param url
 * @return<br>
 */
public static Document getHtmlDoc(String url) {
    if (T.isBlank(url)) {
        return null;
    }
    Document doc = null;
    System.getProperties().setProperty("proxySet", "true"); 
    //用的代理服务器  
    System.getProperties().setProperty("http.proxyHost", 192.168.130.15); 
    //代理端口  
    System.getProperties().setProperty("http.proxyPort", 8080);
    try {
        doc = Jsoup.connect(url).get();  //第一次链接不设延时时间,由于大多数页面的相应时间都是正常的,链接超时的页面为少数
    } catch (Exception e) {  //catch到有java.net.SocketTimeoutException: Read timed out异常则从新请求,且设置延时时间
      try {
        doc = Jsoup.connect(url).timeout(20000).get();  //20000表示延时时间设置为20s
      } catch (IOException e1) {
        e1.printStackTrace();
      }  
    }
    return doc;
}


3.爬虫如何解决ip封锁问题

       http://my.oschina.net/xsh1208/blog/181163 

相关文章
相关标签/搜索