技术心得记录:如何用JAVA爬取AJAX加载后的页面(转载)

简介: 技术心得记录:如何用JAVA爬取AJAX加载后的页面(转载)

之前


之前利用Jsoup做了个小DEMO爬取百度免费API( ),很简单,用Jsoup就可以做到,因为页面加载后的数据填充到html里面,此时查看源代码会看见数据都在源代码里面,这时候可以利用Jsoup爬取,前几天有个需求要爬取天眼查的数据( ),自以为和之前做的DEMO一样,不难,就利用原来的DEMO改改,之后居然获取不到想要的。


需求:搜索(条件包括搜索框,注册资本,地区)


以下是我将要爬取的页面:


搜索:有限


习惯性审查一下要爬取的元素:


这部分是主页面


胸有成竹代码就出来:


Document doc = Jsoup.connect("有限").ignoreHttpErrors(true).timeout(100000).get();


System.out.println(doc.body());


执行--》


[span class="hljs-name">body ng-class="isFromMac ? '':'windows-modal'"


[span class="hljs-name">div id="loading" class="loading" loading=""

[span class="hljs-name">div id="ng-view" ng-view=""

[span class="hljs-name">div ng-cloak="" ng-controller="bannerCtrl"


[span class="hljs-name">div ng-cloak="" ng-if="isPCClient" class="bottom-banner"


[span class="hljs-name">div class="bottom-banner-body2" ng-if="showBanner"

[span class="hljs-name">div class="bottom-banner-box2 company_container"

!【】(//upload-images.jianshu.io/upload_images/3810137-a12c9c8e1c375522.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


[span class="hljs-name">div class="code_box"

!【】(//upload-images.jianshu.io/upload_images/3810137-e7840a271fd37e8e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



!【】(//upload-images.jianshu.io/upload_images/3810137-2dc1551260095554.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


!【】(//upload-images.jianshu.io/upload_images/3810137-2f8c0c671b889cd0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




!【app下载】(//upload-images.jianshu.io/upload_images/3810137-41c6fa56e3e5e7e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




[span class="hljs-name">div ng-show="!isPCClient&&!isTYCClient&&!isWebAppClient"

[span class="hljs-name">div ng-cloak="" ng-show="!showBannerMobile" style="position: fixed;left: 0;bottom:90px;" ng-click="closeClick(showBannerMobile);"

//代码效果参考:http://www.jhylw.com.cn/041036817.html

!【下载天眼查专业版APP】(//upload-images.jianshu.io/upload_images/3810137-93ed2e33708d2d46.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


[span class="hljs-name">div class="bottom-banner-mobile" ng-cloak="" ng-show="showBannerMobile"

!【下载天眼查专业版APP】(//upload-images.jianshu.io/upload_images/3810137-0726860681c21931.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


!【下载天眼查专业版APP】(//upload-images.jianshu.io/upload_images/3810137-fd3b233ccd8b1c0a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


[span class="hljs-name">spana href="" target="_blank"

!【关闭】(//upload-images.jianshu.io/upload_images/3810137-f2a78be96ebe8a57.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)





[span class="hljs-name">script0){var t=document,r=t.getElementsByTagName("head")【0】,a=t.createElement("script");a.async=!0;a.src="";r&&r.insertBefore(a,r.firstChild)}}();

[span class="hljs-name">script0){var t=document.createElement("script");t.src="//hm.baidu.com/hm.js?e92c8d65d92d534b0fc290df538b4758";var r=document.getElementsByTagName("script")【0】;r.parentNode.insertBefore(t,r)}}();


[span class="hljs-name">script type="text/javascript"

[span class="hljs-name">noscript

[span class="hljs-name">p




WTF?


只有这点东西?明明我审查元素的时候有那么多?为什么抓取出来就这么点?这不科学。


爬取的2个办法:


利用Jsoup爬取


利用Ajax请求返回的数据


其一不行,取其二


通过Ajax请求数据,再填充到body里面,于是研究Ajax请求,通过Chrome的NetWork可以抓到:


NetWork


这个接口返回的就是列表的数据,欣喜若狂,这也太简单了,双击访问出现:


错误


WTF2


这。。到底是咋回事


在搜索了很多文章后发现,这个网站本来就是从各大政府网站爬取过来的数据,哪能那么容易就轻松被别人爬取走。况且:


反爬虫工程师


失望中另辟蹊径


失望中又想到另外的办法,既然不能通过Jsoup去爬取,那么是不是有方法可以模拟人为访问,访问后加载完所有的css和js,等数据都返回,再爬取,这不就可以了。


开启搜索引擎一阵搜:


HttpUnit ()


HtmlUnit ()


WebDriver ()


以上方法都是做自动化测试用的,根本不是用来爬取数据的,所以兼容性不能不是很好。各种尝试都没有得到想要的效果。


最后发现了phantomjs ( )。


下载phantomjs后终端就行,加入环境变量自行百度,此处不再多说。


windows下载对应的phantomjs.exe


运行:


/User/music-man/Downloads/phantomjs/phantomjs /User/music-man/Downloads/phantomjs/code.js 有限


注意中间的空格。第一个是phantomjs,第二个是code.js的路径,第三个是爬取的路径。


code.js


system = require('system')


address = system.args【1】;


var page = require('webpage').create();


var url = address;


page.open(url, function (status) {


//Page is loaded!


if (status !== 'success') {


console.log('Unable to post!');


} else {


console.log(page.content);


phantom.exit();


}


});


此时终端执行命令,发现整个页面已经爬取下来。


接下来就是如何与Java结合了。


执行命令Java可以这么做


Runtime rt = Runtime.getRuntime();


String exec = "/Users/music-man/Downloads/phantomjs/phantomjs /Users/music-man/Downloads/phantomjs/code.js " + url;


Process p = rt.exec(exec);


InputStream is = p.getInputStream();


这样就可以获得输入流了,获得输入流之后想要怎么操作就简单了吧。


获取了文件流,想操作dom,如何操作呢?


看了一下Jsoup,发现


输入流转Jsoup


public static Document parse(InputStream in, String charsetName, String baseUri)


第一个参数是输入流,第二个是字符集,第三个是地址:


Document doc = Jsoup.parse(is, "UTF-8", url);


获取到Document再操作dom元素就很明了了。


最后用JFrame做了个界面


不稳定


执行起来发现不稳定,有时候能爬取到页面,有时候就会失败,让我以为是网站做的限制,后来发现多次重复爬取效率过快的话网站会让输入验证码,导致卡住。


解决


爬取不到我初步怀疑是因为爬取的时候页面还没加载完毕,就进行抓取,有时候网速快,加载好了就能抓取到,有时候没有加载好,爬取失败。看了下phantomjs例子()


发现可以采用js的方法setTimeout


最终code.js改为


system = require('system')


address = system.args【1】;


var page = require('webpage').create();


var url = address;


page.open(url, function (status) {


//Page is loaded!


if (status !== 'success') {


console.log('Unable to post!');


} else {


window.setTimeout(function () {


page.render("test1.png"); //截图


console.log(page.content);


phantom.exit();


}, 5000);


}


});


增加了setTimeout方法后,等待5s差不多执行完页面和js,此时再去抓取页面,发现成功率大大提高。


转载自:

相关文章
|
6天前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
33 11
|
15天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
50 7
|
15天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
1月前
|
XML 前端开发 JavaScript
PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑
本文深入探讨了PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑;Ajax则通过异步请求实现页面无刷新更新。文中详细介绍了两者的工作原理、数据传输格式选择、具体实现方法及实际应用案例,如实时数据更新、表单验证与提交、动态加载内容等。同时,针对跨域问题、数据安全与性能优化提出了建议。总结指出,PHP与Ajax的结合能显著提升Web应用的效率和用户体验。
46 3
|
1月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
1月前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
54 6
|
1月前
|
JSON 前端开发 JavaScript
java-ajax技术详解!!!
本文介绍了Ajax技术及其工作原理,包括其核心XMLHttpRequest对象的属性和方法。Ajax通过异步通信技术,实现在不重新加载整个页面的情况下更新部分网页内容。文章还详细描述了使用原生JavaScript实现Ajax的基本步骤,以及利用jQuery简化Ajax操作的方法。最后,介绍了JSON作为轻量级数据交换格式在Ajax应用中的使用,包括Java中JSON与对象的相互转换。
45 1
N..
|
7月前
|
XML JSON 前端开发
jQuery实现Ajax
jQuery实现Ajax
N..
71 1
|
7月前
|
XML 前端开发 JavaScript
jQuery中ajax如何使用
jQuery中ajax如何使用
91 0
|
6月前
|
前端开发 JavaScript
杨校老师课堂之基于Servlet整合JQuery中的Ajax进行表单提交[基于IDEA]
杨校老师课堂之基于Servlet整合JQuery中的Ajax进行表单提交[基于IDEA]
51 0
杨校老师课堂之基于Servlet整合JQuery中的Ajax进行表单提交[基于IDEA]
下一篇
DataWorks