htmlunit抓取动态网页(中国最强搜索引擎--百度上面行走了好长,我要想骂人了)

优采云 发布时间: 2021-12-25 15:20

  htmlunit抓取动态网页(中国最强搜索引擎--百度上面行走了好长,我要想骂人了)

  最近在做一个项目,有一个需求:要从网页中抓取数据,要求是先抓取整个网页的html源代码(用于后期更新)。一开始看到这个简单,然后就稀里糊涂的打了代码(之前用Hadoop平台的分布式爬虫框架Nutch,用起来很方便,但最后因为速度放弃了,但是统计生成用于后续爬取),很快就成功下载了holder.html和finance.html页面,然后在解析holder.html页面后,解析finance.html,然后郁闷的找不到自己需要的在这个页面中的数据不在html源代码中。去浏览器查看源码确实是这样。源代码中确实没有我需要的数据。

  在号称中国最强搜索引擎——百度上走了很久,发现大部分人都在用WebDriver和HttpUnit(其实前者已经收录

了后者)。我很高兴,终于找到了解决方案。. 兴奋地使用WebDriver,我想骂人。

  以下是对WebDriver的投诉

  WebDriver 是一个测试框架。本来不是为爬虫服务的,但我想说的是:星盘只是有点短,你不能更进一步吗?为什么网上那么多人推荐WebDriver?我觉得这些人并没有从现实出发,甚至有人说WebDriver可以解析完成的页面,返回给想要爬取整个页面(包括动态生成的内容)的人。是的,WebDriver可以完成这个任务,但是看关于作者写的代码,我想说的是:哥们,你的代码限制太多了,解析你写的js代码,js代码很简单,所以当然WebDriver 可以毫无压力地完成任务。WebDriver 对动态内容的分析依赖于 js 代码的复杂性和多样性。

  什么是复杂度?

  先贴一段代码

  WebDriver driver = newInternetExplorerDriver ();HtmlPage page = driver.get(url);System.out.println(page.as

  这段代码的意思是大家都明白了。上面使用的IE内核,当然是FirefoxDriver、ChromeDriver、HtmlUnitDriver,这些驱动的使用原理都是一样的,先打开浏览器(这个需要时间),然后加载url并完成动态分析,然后通过page。作为

  什么是多样性

  前面说过,浏览器解析js需要时间。对于只嵌入少量js代码的页面,通过page.as

  WebDriver driver = new InternetExplorerDriver();HtmlPage page = dirver.get(url);Thread.sleep(2000);System.output.println(page.as

  我按照这个想法尝试了以下,是的,确实有可能。但问题不就在那里吗?如何确定等待时间?类似于数据挖掘中使用的经验方法来确定阈值?,或者尽可能长。我觉得这些都不是很好的方法,时间成本也比较高。只是觉得驱动应该可以在js的解析完成后捕捉到状态,于是搜索,搜索,但是根本没有这样的方法,所以我说为什么WebDriver的设计者没有采取措施forward 以便我们可以在程序中获取解析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端要执行的代码

  system = require('system') address = system.args[1];//获得命令行第二个参数 接下来会用到 //console.log('Loading a web page'); var page = require('webpage').create(); var url = address; //console.log(url); page.open(url, function (status) { //Page is loaded! if (status !== 'success') { console.log('Unable to post!'); } else { //此处的打印,是将结果一流的形式output到java中,java通过InputStream可以获取该输出内容 console.log(page.content); } phantom.exit(); });

  在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不熟悉,所以谨慎使用)。

  折腾了几天,虽然我的问题没有解决,但是也长了不少见识。后面的工作熟悉phantomjs,看看速度能不能提高。如果能打破速度框架,以后去网页的时候就方便了。同样,它是 Nutch 框架。我很欣赏使用它时的便利性。后期需要研究如何优化Nutch on Hadoop的爬取速度。另外,Nutch原有的功能不会爬行。动态生成的页面内容,不过你可以用Nutch和WebDirver结合起来,也许爬取的结果是稳定的,哈哈,这些只是想法,不试试怎么知道呢?

  如果你对使用WebDriver辅助爬虫获得的结果的稳定性有什么想说的,欢迎评论,因为我确实没有找到稳定爬虫结果的相关资料。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线