htmlunit抓取动态网页(Web网络爬虫系统的原理及应用)
优采云 发布时间: 2021-12-19 17:14htmlunit抓取动态网页(Web网络爬虫系统的原理及应用)
1、 爬虫技术概述
网络爬虫是根据一定的规则自动抓取万维网信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,可以自动将采集它所能访问的页面的所有内容获取或更新这些网站@的内容和检索方法>. 从功能上来说,爬虫一般分为三部分:数据采集、处理、存储。传统爬虫从一个或多个初始网页的网址开始,获取初始网页上的网址。在爬取网页的过程中,他们不断地从当前页面中提取新的URL并将它们放入队列中,直到满足系统的某个停止条件。聚焦爬虫的工作流程比较复杂。需要按照一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。
与一般的网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
(1) 爬取目标的描述或定义;
(2) 对网页或数据的分析和过滤;
(3) URL 搜索策略。
2、爬取的原理
2.1 网络爬虫原理
网络爬虫系统的作用是下载网页数据,为搜索引擎系统提供数据源。许多大型互联网搜索引擎系统被称为基于Web数据的搜索引擎系统,如谷歌和百度。这说明了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文本信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程就像一个爬虫或蜘蛛在网络上漫游,所以被称为网络爬虫系统或网络蜘蛛系统,英文称为Spider或Crawler。
2.2 网络爬虫系统的工作原理
在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页并处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等内容。爬虫的基本工作由解析器完成。资源库用于存储下载的网页资源。一般使用Oracle数据库等大型数据库存储,并建立索引。
控制器
控制器是网络爬虫的中央控制器。主要负责根据系统传递过来的URL链接分配一个线程,然后启动线程调用爬虫对网页进行爬取。
解析器
解析器是负责网络爬虫的主要部分。它的主要任务包括:下载网页,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
资源库
主要用于存储网页中下载的数据记录,并提供生成索引的目标源。中大型数据库产品包括:Oracle、Sql Server等。
网络爬虫系统一般会选择一些输出度(网页中超链接的数量)较高的比较重要的URL作为*敏*感*词*URL集合。网络爬虫系统使用这些*敏*感*词*集作为初始 URL 开始数据爬取。由于网页收录链接信息,因此可以通过现有网页的网址获取一些新的网址。网页之间的指向结构可以看作是一个森林。每个*敏*感*词* URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能会导致爬虫系统陷入网站内部,不利于搜索更接近< @网站主页,采集网页一般采用广度优先搜索算法。网络爬虫系统首先将*敏*感*词* URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。然后简单地从队列的头部检索一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。然后简单地从队列的头部检索一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。
网络爬虫的基本工作流程如下:
1.先选择一部分精心挑选的*敏*感*词*网址;
2.将这些URL放入URL队列中进行抓取;
3. 从待爬取的URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页并保存到下载的网页库中。另外,将这些网址放入已爬取的网址队列中。
4.对爬取的URL队列中的URL进行分析,分析其中的其他URL,将这些URL放入待爬取的URL队列中,从而进入下一个循环。
2.3 爬取策略
在爬虫系统中,要爬取的URL队列是一个非常重要的部分。URL队列中要爬取的URL按什么顺序排列也是一个很重要的问题,因为它涉及到先爬哪个页面,后爬哪个页面。确定这些 URL 顺序的方法称为抓取策略。下面重点介绍几种常见的爬取策略:
2.3.1 深度优先遍历策略
深度优先遍历策略是指网络爬虫会从起始页开始,逐个跟踪每一个链接,处理完这一行后转移到下一个起始页,继续跟踪链接。我们以下图为例:
遍历的路径:AFG EHI BCD
2.3.2 广度优先遍历策略
广度优先遍历策略的基本思想是将新下载的网页中找到的链接直接插入到待爬取的URL队列的末尾。即网络爬虫会先抓取起始网页中所有链接的网页,然后选择其中一个链接的网页,继续抓取该网页中链接的所有网页。以上图为例:
遍历路径:ABCDEF GHI
2.3.3 反向链接计数策略
反向链接数是指从其他网页链接到某个网页的数量。反向链接的数量表示网页内容被他人推荐的程度。因此,很多时候搜索引擎的爬取系统都会使用这个指标来评估网页的重要性,从而决定不同网页的爬取顺序。
在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量不能完全坐等别人的重视。因此,搜索引擎通常会考虑一些可靠的反向链接。
2.3.4Partial PageRank 策略
Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,连同要爬取的URL队列中的URL,组成一个网页集,计算每个页面的PageRank值,经过计算完成后,将要爬取的URL队列中的URL按照PageRank值的大小进行排列,依次爬取页面。
如果每个页面都被抓取,则重新计算 PageRank 值。一个折衷的方案是:每爬取K个页面后,重新计算PageRank值。但是,这种情况下仍然存在一个问题:对于已经从下载页面中分析出来的链接,也就是我们前面提到的未知网页部分,暂时没有PageRank值。为了解决这个问题,这些页面会被赋予一个临时的PageRank值:将所有传入该页面链中的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排名。以下示例说明:
2.3.5OPIC 策略
该算法实际上对页面的重要性进行评分。在算法开始之前,给所有页面相同的初始*敏*感*词*(cash)。下载某个页面P后,将P的*敏*感*词*分配给所有从P解析的链接,清空P的*敏*感*词*。待抓取的 URL 队列中的所有页面均按照*敏*感*词*的数量进行排序。
2.3.六大站优先策略
URL队列中所有要爬取的网页,按照所属的网站进行分类。网站需要下载的页面较多,优先下载。这种策略因此被称为大站优先策略。
3、 爬虫分类
我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫基本上可以分为三类:
(1)分布式爬虫:Nutch
(2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
(3)非JAVA爬虫:scrapy(基于Python语言开发)
3.1 个分布式爬虫
爬虫采用分布式,主要解决两个问题:
1)海量网址管理
2)网速
最流行的分布式爬虫是 Apache 的 Nutch。但是对于大多数用户来说,Nutch 是这些类型的爬虫中最糟糕的选择,原因如下:
1)Nutch 是一款专为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的一组进程中有三分之二是为搜索引擎设计的。精细提取没有多大意义。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发,让Nutch适合精炼业务,你基本上会破坏Nutch的框架,将Nutch改得面目全非,并有能力修改Nutch。自己写一个新的确实更好。分布式爬虫框架。
2)Nutch 依赖于hadoop 来运行,而hadoop 本身也消耗了大量的时间。如果集群机器数量少,爬取速度不如单机爬虫快。
3) 虽然Nutch有一套插件机制,但也被宣传为一个亮点。可以看到一些开源的Nutch插件,提供精细的提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多烂。使用反射机制加载和调用插件使得编写和调试程序变得极其困难,更不用说在其上开发复杂的精细提取系统了。并且Nutch没有提供相应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点是为搜索引擎服务的,不提供精细提取的挂载点。Nutch的大部分精提取插件都挂载在挂载点“解析器”(parser)上,
4)使用Nutch进行爬虫的二次开发,爬虫的准备和调试所需的时间往往是单机爬虫的十倍以上。学习Nutch源代码的成本非常高,更何况一个团队中的每个人都必须了解Nutch源代码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
5) 很多人说Nutch2有gora,可以持久化数据到avro文件、hbase、mysql等,其实很多人理解错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。这不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
6)Nutch2的版本目前不适合开发。Nutch官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果你想和nutch一起使用hbase(大多数人使用nutch2只是为了使用hbase),你只能在0.90版本左右使用hbase,因此你必须将hadoop版本减少到hadoop 0.2或所以。而且,Nutch2的官方教程更具有误导性。Nutch2有两个教程,分别是Nutch1.x和Nutch2.x。Nutch2.x 官网可以支持转到hbase 0.94。但其实这个Nutch2.x指的是Nutch2.3之前和Nutch2.2.1之后的版本。此版本在官方SVN中不断更新。
所以,如果你不是搜索引擎,尽量不要选择Nutch作为爬虫。有些团队喜欢效仿。他们之所以坚持选择Nutch开发集约化提取的爬虫,其实是因为Nutch的名气(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目被推迟。
如果你是一个搜索引擎,Nutch1.x 是一个非常好的选择。Nutch1.x 与 solr 或 es 合作组成了一个非常强大的搜索引擎。如果非要使用Nutch2,建议等到Nutch2.3发布。当前的 Nutch2 是一个非常不稳定的版本。
分布式爬虫平台架构图
3.2 JAVA爬虫
这里将JAVA爬虫单独划分为一个类别,因为JAVA在网络爬虫的生态系统中是非常完备的。相关资料也是最全的。这里可能有争议,我只是随便说说。
其实开源网络爬虫(框架)的开发非常简单,难点复杂的问题(比如DOM树解析定位、字符集检测、海量URL去重)都已经被前人解决了,可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历机器上的文件以查找文件中的信息。没有任何困难。之所以选择开源爬虫框架,是为了省事。比如爬虫URL管理、线程池等模块任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
用于爬虫的功能。用户比较关心的问题往往是:
1) 爬虫是否支持多线程,爬虫能不能用agent,能不能抓取重复数据,能不能抓取JS生成的信息?
那些不支持多线程、代理、过滤重复URL的不叫开源爬虫,叫循环执行http请求。
js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理页面。所以一种策略是利用这些爬虫来遍历网站,当遇到需要解析的页面时,将页面的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
2)爬虫可以爬取ajax信息吗?
网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax http请求,自己生成ajax请求url,获取返回数据。如果您自己生成 Ajax 请求,那么使用开源爬虫有什么意义呢?其实还是需要用到开源爬虫的线程池和URL管理功能(比如断点爬取)。
如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来抓取这些请求?
爬虫通常被设计成广度遍历或深度遍历的模式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历网站。第一轮爬取是爬取*敏*感*词*集(seeds)中的所有URL。简单的说,就是将生成的ajax请求作为*敏*感*词*,放入爬虫中。使用爬虫遍历这些深度为1的*敏*感*词*(默认为广度遍历)。
3)爬虫如何爬取网站登录?
这些开源爬虫都支持在爬取时指定cookies,模拟登录主要是基于cookies。至于如何获取cookie,就不是爬虫的事情了。您可以手动获取cookies,也可以模拟http请求登录,也可以使用模拟浏览器自动登录获取cookies。
4)爬虫如何从网页中提取信息?
开源爬虫一般都集成了网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,这里就不评价了。
5)爬虫是如何保存网页信息的?
一些爬虫带有一个负责持久化的模块。例如,webmagic 有一个叫做管道的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等中,也有一些爬虫不直接为用户提供数据持久化模块。如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于使用pipeline模块好不好,类似于是否使用ORM来操作数据库的问题,看你的业务了。
6)爬虫被网站屏蔽了,怎么办?
爬虫已经被网站拦截了,通常可以通过多个代理(随机代理)解决。但是,这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,自己编写代码来随机获取代理(从数组中)。
7)网页可以调用爬虫吗?
爬虫的调用是在Web的服务器端调用的,你可以照常使用。这些爬虫都可以使用。
8)爬行速度怎么样?
一个单机的开源爬虫的速度基本可以用到机器网速的极限。爬虫速度慢,往往是因为用户线程少,网速慢,或者持久化数据时与数据库交互速度慢。而这些东西往往是由用户的机器和二次开发代码决定的。这些开源爬虫的速度非常好。
9)显然代码写对了,爬不出来数据。是不是爬虫有问题?别的爬虫能解决吗?
如果代码写对了,数据爬不出来,其他爬虫也是一样。在这种情况下,要么 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。无法通过更换爬虫来解决抓取数据失败的问题。
10)哪个爬虫可以判断网站是否爬完了,哪个爬虫可以根据主题爬取?
爬虫无法判断网站是否已经爬过,只能尽量覆盖。
至于基于主题的爬取,爬虫只有向下爬取内容才知道主题是什么。所以它通常是从整体上爬下来,然后去过滤内容。如果觉得抓取过于笼统,可以通过限制网址规律等方法缩小范围。
11) 哪个爬虫有更好的设计模式和结构?
设计模式纯属无稽之谈。当软件设计模式好的时候,开发软件,然后总结出几种设计模式。设计模式对软件开发没有指导作用。使用设计模式来设计爬虫只会让爬虫的设计更加臃肿。
在架构上,开源爬虫目前主要是详细数据结构的设计,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,不谈结构。
所以对于JAVA开源爬虫,我想,找一个好用的就好了。如果业务复杂,使用哪种爬虫就必须经过复杂的二次开发才能满足需求。
3.3 个非 Java 爬虫
在非JAVA语言编写的爬虫中,有很多优秀的爬虫。这里单独提取为一个类别,不是针对爬虫本身的质量,而是针对larbin、scrapy等爬虫对开发成本的影响。
先说python爬虫,python可以用30行代码完成JAVA 50行代码的任务。Python 代码编写确实很快,但是在调试代码阶段,Python 代码的调试往往比编码阶段节省的时间消耗的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务不复杂,使用scrapy也是相当不错的,可以轻松完成爬取任务。
上图是Scrapy的架构图。绿线是数据流。首先,从初始 URL 开始,Scheduler 将其交给 Downloader 进行下载。下载完成后,会交给Spider进行分析。需要保存的数据会被发送到Item Pipeline。,即对数据进行后处理。此外,可以在数据流通道中安装各种中间件来进行必要的处理。所以在开发爬虫的时候,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
对于C++爬虫来说,学习成本会比较大。而且你不能只计算一个人的学习成本。如果软件需要团队开发或交接,那将是很多人的学习成本。软件调试并不是那么容易。
还有一些ruby、php爬虫,这里不多评论。确实有一些非常小的数据采集任务,用ruby或者php非常方便。但是要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能会产生一些你找不到的bug(人少信息少)
4、反爬虫技术
由于搜索引擎的流行,网络爬虫已经成为一种非常流行的网络技术。除了专门从事搜索的谷歌、雅虎、微软和百度,几乎每个大型门户网站网站都有自己大大小小的搜索引擎。可以叫出的名字有几十个,不知道的名字也有上万个。对于一个内容驱动的网站来说,难免会被网络爬虫光顾。
网站上一些智能搜索引擎爬虫的爬取频率比较合理,消耗的资源比较少。但是,很多不良的网络爬虫对网页的爬取能力较差,经常会发送几十甚至上百个请求,重复爬取循环。拿,这种爬虫往往对中小网站是毁灭性的打击,尤其是缺乏爬虫编写经验的程序员写的爬虫,破坏力极强,网站的访问压力会非常大。, 会导致网站 访问缓慢甚至无法访问。
一般来说,网站从三个方面进行反爬虫:用户请求的Headers、用户行为、网站目录和数据加载方式。前两个比较容易遇到,从这些角度来看,大多数网站都是反爬虫。将采用第三类ajax应用网站,增加爬虫难度。
4.1 个通过 Headers 的反爬虫
从用户请求的Headers反爬取是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(部分资源网站的防盗就是检测Referer)。如果遇到这种反爬虫机制,可以直接给爬虫添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者修改Referer值为目标网站域名【注:经常容易被Ignore,通过对请求的抓包分析确定referer,将其添加到模拟访问的请求头中该程序]。对于检测header的反爬虫,在爬虫中修改或添加header很容易绕过。
4.2 基于用户行为的反爬虫
网站的另一部分是检测用户行为,比如在短时间内从同一个IP多次访问同一个页面,或者在短时间内在同一个账号内多次执行相同的操作. 【这种反爬需要足够的ip来应对】
大部分网站都是前一种情况。在这种情况下,使用IP代理可以解决。可以专门写一个爬虫来爬取网上公开的代理ip,检测后全部保存。这类代理ip爬虫经常用到,最好自己准备一个。代理IP数量较多后,可以每隔几次请求换一个IP。这在requests或urllib2中很容易做到,这样你就可以轻松绕过第一个反爬虫。【点评:动态拨号也是一种解决方案】
在第二种情况下,您可以在每次请求后以几秒钟的随机间隔发出下一个请求。一些存在逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求来绕过同一账号不能在短时间内多次发出相同请求的限制。【评论:账号的反爬限制一般很难处理,几秒的随机请求也可能被屏蔽。如果有多个账号,在它们之间切换会有更好的效果】
4.3 动态页面反爬虫
以上情况大部分出现在静态页面上,还有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。首先使用Firebug或者HttpFox来分析网络请求【点评:感觉google和IE的网络请求分析也很好】。如果能找到ajax请求,分析出响应的具体参数和具体含义,就可以通过上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
能够直接模拟ajax请求获取数据是很棒的,但是有的网站加密了ajax请求的所有参数。我们没有办法为我们需要的数据构造一个请求。这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,对接口参数进行加密。遇到这样的网站,就不能用上面的方法了。我使用selenium+phantomJS框架,调用浏览器内核,使用phantomJS执行js模拟人的操作,触发页面中的js脚本。从填表到点击按钮再到滚动页面,一切都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。【评论:支持phantomJS】
使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面是在一定程度上通过添加Headers来冒充浏览器),它是浏览器本身,phantomJS是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别point-and-touch(12306)或滑动验证码,页面表单的暴力破解等)。它还将在自动化渗透方面大显身手,未来也会如此。提这个。