httpunit 抓取网页(中国最强搜索引擎--百度上面行走了好长,我要想骂人了)
优采云 发布时间: 2022-03-15 18:21httpunit 抓取网页(中国最强搜索引擎--百度上面行走了好长,我要想骂人了)
最近在做一个项目的时候,有个需求:从一个网页抓取数据,需求是先抓取整个网页的html源码(用于以后的更新)。一开始看到这么简单,然后乱码乱码(之前用的是Hadoop平台的分布式爬虫框架Nutch,用起来很方便,最后因为速度问题放弃了,但是生成的统计信息用于后续爬取),很快就成功下载了holder.html和finance.html页面,解析了holder.html页面后,解析了finance.html,然后很郁闷的在这个页面中找到了自己需要的东西数据不在 html 源代码中。去浏览器查看源码确实是这样。源代码中确实没有我需要的数据。看来我的程序没有错。- 获取具有动态内容的 html 页面。html
在号称国内最强的搜索引擎——百度上走了很久,发现大部分人都在用WebDriver和HttpUnit(其实前者已经收录了后者)。我很高兴我终于找到了解决方案。. 如此兴奋地使用 WebDriver,我想诅咒。爪哇
以下是关于WebDriver的吐槽网
WebDriver 是一个测试框架。本来不是为爬虫服务的,但我想说的是:八个字就差一步了,就不能再往前走一步吗?为什么网上那么多人推荐WebDriver?我不认为这些人是基于现实的,甚至有人说WebDriver可以解析完成的页面并将其返回给那些想要爬取整个页面(包括动态生成的内容)的人。是的,WebDriver 可以完成这个任务,但是看到至于作者写的代码,我想说的是:哥们,你的代码太局限了,解析自己写的js代码,js代码简单,所以WebDriver 可以毫无压力地完成任务。WebDriver解析动态内容时,取决于js代码的复杂性和多样性。浏览器
什么是复杂性?框架
先贴一段代码jvm
WebDriver driver = newInternetExplorerDriver ();
HtmlPage page = driver.get(url);
System.out.println(page.asXml());
这段代码的意思相信大家都懂。上面用到的IE内核,当然还有FirefoxDriver、ChromeDriver、HtmlUnitDriver。使用这些驱动的原理都是一样的,先打开浏览器(这需要时间),然后加载url并完成动态解析,然后通过page.asXml()就可以得到完成的html页面,其中HtmlUnitDriver模拟了一个非接口浏览器,java有一个引擎rhino执行js,而HtmlUnitDriver使用rhino来解析js,因为它不会启动带接口的浏览器,所以HtmlUnitDriver比前面三个要快。不管是什么驱动,解析js都是不可避免的,这需要时间,而且不同内核对js的支持方案也不一样。比如HtmlUnitDriver不支持滚动好的js代码,并且会报错(亲身经历)。js代码的复杂性意味着它们所支持的js对于不同的内核来说并不完全相同。这个要根据具体情况来确定。好久没研究js了,就不说各个内核对js的支持了。. 分散式
什么是多样性工具
前面说过,浏览器解析js是需要时间的。对于只嵌入少量js代码的页面,通过page.asXml()获取完整页面是没有问题的。但是对于内嵌js代码较多的页面,解析js需要花费很多时间(对于jvm),那么通过page.asXml()获取的页面大部分时间是不收录动态生成的。内容。问题来了,为什么还说WebDriver可以获取收录动态内容的html页面呢?网上有人说在driver.get(url)之后,当前线程需要等待一段时间才能得到完成的页面,类似于下面的形式oop
WebDriver driver = new InternetExplorerDriver();
HtmlPage page = dirver.get(url);
Thread.sleep(2000);
System.output.println(page.asXml());
我按照这个想法尝试了以下,是的,确实可以。但问题不就在那里吗?如何确定等待时间?类似于数据挖掘中确定阈值的经验方法?, 仍然尽可能长。我觉得这些都不是很好的解决方案,时间成本也比较高。我只是觉得驱动解析js后应该可以捕获状态,于是去找找找,但是根本没有这个方法,所以说为什么WebDriver的设计者从来没有前行过,这样我们就可以在程序中,得到解析js后驱动的状态。在这种情况下,没有必要使用Thread.sleep(2000)等不确定的代码。可惜我找不到。真的让我心痛。一个。FirefoxDriver,ChromeDriver,HtmlUnitDriver 也有同样的问题。可以说,使用WebDriver辅助爬取动态生成的网页得到的结果非常不稳定。我对此有深刻的理解。在使用IEDriver的时候,同样的两个页面爬取的结果会不一样,有时候IE甚至会直接挂掉。你敢在爬虫程序中使用这样的东西吗?我不敢。邮政
另外,有人推荐使用 HttpUnit。其实WebDirver中的HtmlUnitDriver内部使用的是httpUnit,所以使用HttpUnit也会遇到同样的问题。我也做了一个实验,确实如此。在 Thread.sleep(2000) 之后等待js解析完成,我觉得是不可取的。不确定性太大,尤其是在*敏*感*词*爬取工作中。
综上所述,WebDriver 是一个为测试而设计的框架。虽然理论上可以用来辅助爬虫根据其原理获取收录动态内容的html页面,但在实际应用中并没有使用,不确定性太大。稳定性太差,速度太慢,让框架尽其所能吧,不要妥协自己的优势。
个人的工作还没有完成,所以我继续上网寻找方法。这次找到了一个稳定的、高确定性的辅助工具——phantomjs。目前,我还没有完全理解这个东西。但现在我已经用它来实现我想要的。在java中通过runtime.exec(arg)调用phantomjs获取解析js后的页面。我仍在发布代码
phantomjs端要执行的代码
在java端执行的代码
public void getParseredHtml(){
String url = "www.bai.com";
Runtime runtime = Runtime.getRuntime();
runtime.exec("F:/phantomjs/phantomjs/phantomjs.exe F:/js/parser.js "+url);
InputStream in = runtime.getInputStream(); //后面的代码省略,获得了InputStream就好说了 }
这样就可以在java端获取解析后的html页面,而不是使用WebDriver中的Thread.sleep()等不确定的代码来获取可能的完整代码。需要说明一点:phantomjs端的js代码一定不能有语法错误,否则如果js代码编译不一样,java端会一直等待,不会抛出异常。那是因为在使用phantomjs.exe的时候,java端每次都要打开一个phantomjs进程,耗时还是比较大的。但至少结果是稳定的。虽然最后没有使用phantomjs,但是直接下载了需要的数据,并没有抓取整个页面,主要是速度问题(其实我也不敢用,因为对phantomjs不熟悉,所以我谨慎使用它)。
折腾了几天,虽然没有解决我个人的问题,但也收获了很多知识。后面的工作就是熟悉phantomjs,看看能不能提高速度。如果能突破限速,爬到网页就熟悉了。,以及 Nutch 的框架。我很佩服我的伙伴们在使用它时的便利。后期有必要研究如何优化Nutch on Hadoop的爬取速度。此外,Nutch 原有功能不会抓取动态。生成的页面内容可以结合Nutch和WebDirver,说不定爬取结果是稳定的,哈哈,这些只是想法,不试试怎么知道呢?
如果园丁对使用WebDriver辅助爬虫得到的结果的稳定性有什么想说的,不客气,因为我确实没有找到相关资料稳定爬取结果。