htmlunit抓取动态网页(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
优采云 发布时间: 2022-02-15 21:20htmlunit抓取动态网页(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
由于其他项目组都在做舆情预测项目,我只是手头没有项目,突然心血来潮想研究一个简单的爬虫原型和分析。网上这方面的资料很多,看得我眼花缭乱。对于我这样的新手,想做一个简单的爬虫程序,所以HttpClient + jsoup是个不错的选择。前者是用来管理请求的,后者是用来解析页面的,主要是后者的select语法和jquery很像,对我这个用js的人来说太方便了。
昨天和他们聊天时,他们使用了几个知名的开源框架。聊了几句,他们发现自己根本无法爬取动态网页,尤其是一些重要的数字,比如评论数和回复数。等等我有一个大致的了解。比如TRS的爬虫需要为js调用编写js脚本,但分析量巨大。他们的技术人员告诉我们,如果他们匹配这样的模板,他们每天只能匹配2到3个。,更何况我们这些中途修士。碰巧是一个相当大的挑战,所以我昨天答应他们,看看他们是否能找到一个相对简单的解决方案,当然,不管效率如何。
举个简单的例子,如下图
“我有话要说”后面的1307是后载的,但这些数字往往对舆情分析更重要。
对需求有了大致的了解后,我们来分析如何解决它们。通常我们得到的一个请求的响应收录js代码和html元素,所以像jsoup这样的html解析器很难在这里利用,因为它所能得到的html,1307还没有生成。这时候就需要一个可以运行js的平台,运行js代码后的页面会被html解析,这样才能正确得到结果。
因为懒,一开始写脚本的方式被我抛弃了,因为分析一个页面太痛苦了,代码乱成一锅粥。看的太累了。所以我的首要任务是,为什么我不能让这个地址在某个浏览器中运行,然后将运行结果交给html解析器解析,那么整个问题就解决了。这样,我的临时解决方案是在爬虫服务器上打开一个后台浏览器,或者是有浏览器内核的程序,把url地址交给它去请求,然后从浏览器中取出页面的元素给它到 html 解析器进行解析以获取您想要的信息。
没错,最后我还是用 Selenium 来实现我在上一篇文章中提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果我还是可以接受的。
继续昨天的话题,既然我们要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的首选是htmlunit,先简单介绍一下htmlunit。以下段落摘自互联网。
htmlunit 是一个开源的java页面分析工具。启动htmlunit后,会在底层启动一个非界面浏览器。用户可以指定浏览器类型:firefox、ie等,不指定则默认使用INTERNET_EXPLORER_7:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
只需调用:
HtmlPage 页面 = webClient.getPage(url);
可以获取页面的 HtmlPage 表示,然后通过:
InputStream 是 = targetPage.getWebResponse().getContentAsStream()
可以获取页面的输入流,从而获取页面的源代码,对于网络爬虫项目非常有用。
当然,你也可以从page中获取更多的页面元素。
重要的是,HtmlUnit 提供对执行 javascript 的支持:
page.executeJavaScript(javascript)
执行js后,返回一个ScriptResult对象,通过该对象可以获取执行js后的页面等信息。默认情况下,执行完js后,内部浏览器会进行页面跳转,跳转到执行完js后生成的新页面。如果js执行失败,则不会执行页面跳转。
最后可以通过page.executeJavaScript(javascript).getNewPage()获取执行的页面。也就是说,这里需要人为地执行javascript,这显然不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻的页面时总是出错。根据网络上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数顺序或者编码问题,请求失败,报错。关键是,运行它后我没有得到我需要的结果。
然后我寻找另一种解决方案。这时,我找到了 SeleniumWebDriver,这是我需要的解决方案。
参考资料和例子,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn");
11 list.add("http://www.sohu.com");
12 list.add("http://www.163.com");
13 list.add("http://www.qq.com");
14
15 long start,end;
16
17 for(int i=0;i