java模拟浏览器包selenium整合了htmlunit,火狐浏览器,IE浏览器,opare浏览器驱
//如果网页源码中有些内容是js渲染过来的,那你通过HttpClient直接取肯定取不到,但是这些数据一般都是通过异步请求传过来的(一般都是通过ajax的get或者post方式)。那么你可以通过火狐浏览器的firebug或者chrome的审查元素,在网络选项中找到这个请求地址,再用HttpClient请求一次就可以拿到你想要的数据,但这些数据可能不是网页源码,一般都是json字符串。
//朋友你好我现在是HtmlUnit运用者,我现在在项目爬去中遇见一个非常棘手的问题,就是分页数据怎样爬取,我现在真的不明白了,朋友可以的话加我QQ452276647 这个问题解决了非常非常的感谢了,
// java模拟浏览器包htmlunit,selenium
//发现一个很不错的模拟浏览器包htmlunit,它可以直接执行访问网站地址,并执行相应的JavaScript脚本;这个功能对于网站爬虫有很大的帮助,一些网站使用了ajax,如果使用简单的http访问只能抓到原始的html源码,但对于页面内执行的ajax却无法获取;使用这个包后,可以将执行ajax后的html源码一并抓取下来。
//网站地址:http://htmlunit.sourceforge.net/
//该站点下边还提到了几个相类似的包:HtmlUnit is used as the underlying "browser" by different Open Source tools like Canoo WebTest, JWebUnit, WebDriver, JSFUnit, Celerity, ...
//canoo WebTest 看了一下,没太明白是怎么用的,没想太深入了解
//jwebunit 是用来做网站测试用的,它整合了JUnit,htmlunit,selenium 包框架;其主要功能是用做白盒测试和压力测试。
//webDriver 后来改名为selenium,它整合了htmlunit,火狐浏览器,IE浏览器,opare浏览器驱动。如果使用htmlunitDriver,则是使用htmlunit包来访问站点;如果使用FirefoxDriver则会直接将Firefox浏览器调出来,然后在浏览器上模拟输入文字和其他鼠标键盘事件。
//htmlunit包访问网站后,获取到html源码后可以对源码进行修改;而jwebunit,selenium则暂时没有发现修改的功能,只是用来做模拟用户操作的功能。
AJAX 网页抓取部分采用调用浏览器 API 的方法,将浏览器虚拟
为一个代理服务器,并将浏览器服务绑定到电脑指定的端口上,通过和这个浏览器
通信并发送网页请求、连接、关闭等指令,实现 AJAX 网页的载入,并将最终载入
完成、重塑之后的网页内容进行保存,并进行后期处理。爬取后的网页将进行去噪、
网页正文抽取和重抓调度等操作。
I am trying to understand testing framework better and been looking into Selenium. I've used HTMLUnit before, mainly when I needed to scrape some information off website or the likes.
In the context of writing test automation, what's the advantage / disadvantages of Selenium vs HTMLUnit? Looks to me Selenium is more complicated to set up than HTMLUnit, although at the same time there's a HTMLUnitDriver for Selenium which I think behave the exact same way as in HTMLUnit itself?
Selenium obviously provides more robust framework, it has the Selenium RC for pararel testing, it also has different browser drivers that can be used - although when you used the browser drivers, the test will actually open/close a browser application rather than headless.
May be I am not understanding Selenium correctly. Some directions and pointers would be great!
On another note - a separate question - I am also looking at doing automated testing on mobile browser, I see that Selenium has an IPhoneDriver for it, but then this is not a headless testing either as it requires actual iOS simulator.
Speaking about parallel testing, it better to use selenium grid. Basic concept of selenium RC and selenium grid.
静态化还有一种思路就要采用HttpClient获取首页生成的html文件保存作为静态页,但是很不幸的,HttpClient无法执行js,所有使用ajax获取的数据都无法获取到,于是这种方式也行不通
最后使用HtmlUnit. HtmlUnit的优势就是可以支持大部分js,对JQuery的支持也不错.大体思路就是先使用HtmlUnit获取执行完js的html, 这个html 生成的样式和html格式会出现一些问题.如果能满足需求则可以直接使用或者略加改动后使用.
很多方案:selenium,phantomjs,casperjs,qtwebkit等。
一般采用的是casperjs。把每个ajax请求完成后保存网页,放入队列,这样的话后面的分析程序就只要分析html就好了。
casperjs这货和nodejs一起使用的时候时不时会有点小问题,如果不想麻烦,npm安装spookyjs,可以把casperjs作为node的模块来使用了。
当然,请求不复杂,无需验证的话,直接观察请求就可以了。
要想做的通用,只能通过浏览器上入手。windows上可以用程序调用IE的浏览器接口来获取页面document,还可以通过chrome或者firefox插件形式来获取要采集的信息后post到服务器上。linux下可以通过phantomjs操纵webit来获取document的内容。phantomjs有好多优点:不依赖X,可以工作在文本模式下,官网里叫做headless;可以抓取页面截图;能监视网络传输;可以禁用图片加载;自定义cookie,自定义头信息等。
使用HtmlUnit. HtmlUnit的优势就是可以支持大部分js,对JQuery的支持也不错.大体思路就是先使用HtmlUnit获取执行完js的html, 这个html 生成的样式和html格式会出现一些问题.如果能满足需求则可以直接使用或者略加改动后使用.
如果这个html不能满足需求,那么就把它当做 为静态数据来使用.这个时候我们先需要一个html模板文件,这个模板文件要保证首页的主题框架,然后从html按照各个div将数据填充进去.下面贴一些实现代码.
//创建一个可执行js,css,ajax的多功能WebClient
WebClient multiWebClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_8);
multiWebClient.setJavaScriptEnabled(true);//执行JavaScript
multiWebClient.setCssEnabled(true);//执行css
multiWebClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置ajax代理
//创建一个普通的WebClient
WebClient commmonWebClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_8);
commmonWebClient.setJavaScriptEnabled(false);
commmonWebClient.setCssEnabled(false);
//用多功能Client获取动态页面的html并执行完js后的页面
URL dynamicUrl = new URL("http://localhost:30010/WebSite");
HtmlPage dynamicPage = (HtmlPage) multiWebClient.getPage(dynamicUrl);
//根据项目需要,使用普通Client加载首页模板(避免执行模板里面的js,这些js都是真正要浏览器查看的时候才会执行)
URL constantUrl = new URL("http://localhost:30010/WebSite/wwwroot/indexTemple.html");
HtmlPage htmlpage = (HtmlPage) commmonWebClient.getPage(constantUrl);
HtmlElement body = htmlpage.getBody();
/**
* 未详细测试的结论:getElementById一个元素只能取一次,取了之后再取就是空元素,其子也无法用getElementById取到
* 开始处理header
*/
appendChildren(body.getElementById("_static_nav"), dynamicPage.getElementById("_static_nav"));
//开始处理_static_leftbox
//处理图片滚动KSS_content
appendChildren(body.getElementById("KinSlideshow"), dynamicPage.getElementById("KSS_content"));
//处理最新电子书
appendChildren(body.getElementById("e_bookDiv"), dynamicPage.getElementById("e_bookDiv"));
//取出content
HtmlElement content = body.getElementById("content");
//开始处理_static_rightbox
content.appendChild(dynamicPage.getElementById("_static_rightbox"));
//添加div换行
DomElement clearDiv = htmlpage.createElement("div");
clearDiv.setAttribute("class", "clear");
//一个DomElement貌似只能使用一次
content.appendChild(clearDiv.cloneNode(true));
//开始处理_static_bookshow
content.appendChild(dynamicPage.getElementById("_static_bookshow"));
content.appendChild(clearDiv.cloneNode(true));
//开始处理_static_assistBox,secrecyRelevancediv,_static_optionBox
content.appendChild(dynamicPage.getElementById("_static_assistBox"));
content.appendChild(dynamicPage.getElementById("secrecyRelevancediv"));
content.appendChild(dynamicPage.getElementById("_static_optionBox"));
content.appendChild(clearDiv.cloneNode(true));
//开始处理_static_bookShowA
content.appendChild(dynamicPage.getElementById("_static_bookShowA"));
content.appendChild(clearDiv.cloneNode(true));
//开始处理_static_serve
content.appendChild(dynamicPage.getElementById("_static_serve"));
//开始处理footer
body.appendChild(clearDiv.cloneNode(true));
body.appendChild(dynamicPage.getElementById("_static_footer"));
//处理错误
String finalHtml =htmlpage.asXml().replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
finalHtml = finalHtml.replaceAll("<a class=\"prev browse left\"/>", "<a class=\"prev browse left\" ></a>");
finalHtml = finalHtml.replaceAll("<a class=\"next browse right\"/>", "<a class=\"next browse right\" ></a>");
finalHtml = finalHtml.replaceAll("<b/>", "<b></b>");
finalHtml = finalHtml.replaceAll("scrollable_2", "scrollable");
stringToFile(finalHtml,"E:\\WayOfGlory\\WebSite\\WebContent\\wwwroot\\indexHome.html");
上面一段代码虽然不长,但实际上是个非常漫长的处理过程,从静态数据html中获取到的<div></div>经常会无法直接 使用,这时就需要不断的和浏览器(比如chrome)生成的真正静态页进行比对.虽然过程很漫长,但总比无法实现要强.
下面贴上刚刚使用了的两个小方法.
public DomElement appendChildren(DomElement target,DomElement source){
Iterator it = source.getChildElements().iterator();
while(it.hasNext()){
DomElement ele = (DomElement) it.next();
target.appendChild(ele);
}
return target;
}
public void stringToFile(String content,String path){
try {
FileWriterWithEncoding fileWriter = new FileWriterWithEncoding(path,"utf-8");
fileWriter.write(content);
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Selenium HtmlUnitDriver多浏览器的支持
java模拟浏览器包selenium整合了htmlunit,火狐浏览器,IE浏览器,opare浏览器驱的更多相关文章
- 浏览器与服务器交互原理以及用java模拟浏览器操作v
浏览器应用服务器JavaPHPApache * 1,在HTTP的WEB应用中, 应用客户端和服务器之间的状态是通过Session来维持的, 而Session的本质就是Cookie, * 简单的讲,当浏 ...
- Java 模拟面试题
1.面向对象的特点 继承,封装,多态 2.对象和类的区别是什么? 对象是对客观事物的抽象,类是对对象的抽象.类是一种抽象的数据类型,它们的关系是,对象是类的实例,类是对象的模板. 3.静态成员和实例成 ...
- Jsoup实现java模拟登陆
Jsoup实现java模拟登陆 2013-10-29 14:52:05| 分类: web开发|举报|字号 订阅 下载LOFTER我的照片书 | 1:如何获取cookies. 1.1 ...
- [Java] 模拟HTTP的Get和Post请求
在之前,写了篇Java模拟HTTP的Get和Post请求的文章,这篇文章起源与和一个朋友砍飞信诈骗网站的问题,于是动用了Apache的comments-net包,也实现了get和post的http请求 ...
- 阿里Java面经大全(整合版)
本文里的面经内容全部来源于牛客网,作为秋招备战复习与查缺补漏时使用.里面部分面经有我的注释和想法,以及部分解答,不一定正确,大家可以查询补充. 阿里巴巴,三面,java实习 昨天晚上11点打电话来,问 ...
- Java常用jar包用途
Java常用jar包用途: USAGE INDEX JAR NAME USAGE 1 ASM asm-2.2.3.jar ASM字节码库 2 ASM asm-commons-2.2.3.jar ASM ...
- java.util.concurrent包API学习笔记
newFixedThreadPool 创建一个固定大小的线程池. shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭. awaitTermination():用于等待子线程结束, ...
- Java中的包含义
JAVA提供了强大的应用程序接口,既JAVA类库.他包含大量已经设计好的工具类,帮助程序员进行字符串处理.绘图.数学计算和网络应用等方面的工作.下面简单介绍JAVA核心类库中常用的组建包. 1.jav ...
- EscapeAndUnescapeUtil【java模拟js的escape和unescape函数】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 在这里做一个记录,基本代码同参考资料<java模拟js的escape和unescape函数>一样. 效果图 代码 ...
随机推荐
- 国内使用Google Maps JavaScript API
<!DOCTYPE html> <html> <head> <meta name="viewport" content="ini ...
- 如何编译tizen源码(图文教程)?
前一篇文章已经介绍了如何下载tizen源码,下面我将继续讲述如何编译源码. 1 下载安装gbs编译工具 tizen源码是用gbs工具进行编译的,因此我们首先得将此工具下载下来,并且设置好. 下面的Ub ...
- sharepoint 2010 在自定义列表的字段上增加功能菜单
sharepoint 2010 在自定义列表的字段上增加功能菜单方法 打开sharepoint designer 2010,找到需要修改的视图页面,例如allitem.aspx,编辑这个页面,点击高级 ...
- MySQL 暂时文件夹
MySQL数据文件夹/data/mysql所在的上层文件夹/data磁盘空间不足导致MySQL启动失败,所以清理了/data文件夹下除了mysql子文件夹外的其它无用文件夹.重新启动发现还是失败.检查 ...
- abap四舍五入的函数
VALUE '1.6'. DATA p2 TYPE i . CALL FUNCTION 'ROUND' EXPORTING DECIMALS = input = p1 SIGN = '+ ' IMPO ...
- jyphon 环境变量配置
Jyphon 是基于java平台python 的一种实现 官网: http://www.jython.org/ 可以从官网下载 jyphon 安装 下载 jython Installer ,下载之后是 ...
- 解决 Android SDK Manager不能下载旧版本的sdk的问题
解决无法使用Android SDK Manager下载SDK开发包的解决办法. 当我们在官网下载google的集成ADT,也就是adt-bundle-linux-x86.zip开发包,进行解压, 打 ...
- IOS 轻量级数据持久化 DataLite
开发的过程中我们经常要保存一些配置信息,一般简单的是用 NSUserDefaults [[NSUserDefaults standardUserDefaults] objectForKey:key]; ...
- Matlab的parfor并行编程
Matlab的parfor并行编程 通常消耗最多计算资源的程序往往是循环. 把循环并行化.或者优化循环体中的代码是最经常使用的加快程序执行速度的思路. Matlab提供了parforkeyword,能 ...
- java中synchronized的使用方法与具体解释
Java语言的keyword.当它用来修饰一个方法或者一个代码块的时候,可以保证在同一时刻最多仅仅有一个线程运行该段代码. 一.当两个并发线程訪问同一个对象object中的这个synchronized ...