js 爬虫抓取网页数据(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
优采云 发布时间: 2021-12-14 15:18js 爬虫抓取网页数据(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
因为其他项目组都在做舆情预测项目,我只是手头没有项目,突然想研究一个爬虫的简单原型,心血来潮分析。网上查这方面的资料太多了,看得我眼花缭乱。Search Search 对于我这种新手,想做一个简单的爬虫程序,HttpClient + jsoup 是个不错的选择。前者是用来管理请求的,后者是用来解析页面的,主要是因为后者的select语法和jquery很像,对我这个用js的人来说太方便了。
昨天和他们聊天的时候,他们选择了几个知名的开源框架来使用,聊天后发现他们目前没有办法抓取动态网页,尤其是几个重要的数字,比如评论数量和数量的答复。等等,一般的理解,比如TRS爬虫需要写js脚本来调用js,但是分析量巨大。他们的技术人员告诉我们,如果他们配备了这样的模板,他们一天只能配备2到3个,更不用说我们这些中途出家的人了。碰巧挺有挑战性的,所以昨天就同意了,看看他们能不能找到一个相对简单的解决方案,当然,不考虑效率。
举个简单的例子,如下图
“我有话要说”后面的1307是后装的,但这些数字往往对舆论分析更重要。
对需求有了大致的了解之后,我们来分析一下如何解决。通常我们对一个请求得到的响应收录js代码和html元素,所以像jsoup这样的html解析器很难在这里利用它,因为它可以得到的html,1307还没有生成。这时候就需要一个可以运行js的平台,将运行js代码后的页面交给html进行解析,这样才能正确得到结果。
因为比较懒,一开始就放弃了写脚本的方式,因为分析一个页面太痛苦,代码乱七八糟。其中很多也使用了压缩方法,都是a()、b()方法。看的太累了。所以我的第一个想法是,为什么我不能让这个地址在某个浏览器中运行,然后将运行的结果传递给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()
可以获取页面的输入流,进而获取页面的源代码,这对于网络爬虫项目非常有用。
当然,你也可以从页面中获取更多的页面元素。
很重要的一点是 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