文档章节

Htmlunit 使用表示例

诺岚
 诺岚
发布于 2017/08/30 09:14
字数 1812
阅读 28
收藏 1
点赞 0
评论 0

第一组示例将使用这个简单的html。

<html><head><title>Table sample</title></head><body>
    <table id="table1">
        <tr>
            <th>Number</th>
            <th>Description</th>
        </tr>
        <tr>
            <td>5</td>
            <td>Bicycle</td>
        </tr>
    </table>
</body></html>

此示例显示如何遍历所有行和单元格

HtmlTable table = page.getHtmlElementById("table1");
for (HtmlTableRow row : table.getRows()) {
    System.out.println("Found row");
    for (HtmlTableCell cell : row.getCells()) {
     System.out.println("  Found cell: " + cell.asText());
    }
}

以下示例显示如何按行和列访问特定单元格

WebClient webClient = new WebClient();
HtmlPage page = webClient.getPage("http://foo.com");

HtmlTable table = page.getHtmlElementById("table1");
System.out.println("Cell (1,2)=" + table.getCellAt(1,2));

更复杂的表

下面的例子将使用一个更复杂的表,其中包括表头,页脚和主体部分以及标题

<html><head><title>Table sample</title></head><body>
    <table id="table1">
        <caption>My complex table</caption>
        <thead>
            <tr>
                <th>Number</th>
                <th>Description</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <td>7</td>
                <td></td>
            </tr>
        </tfoot>
        <tbody>
            <tr>
                <td>5</td>
                <td>Bicycle</td>
            </tr>
        </tbody>
        <tbody>
            <tr>
                <td>2</td>
                <td>Tricycle</td>
            </tr>
        </tbody>
    </table>
</body></html>

HtmlTableHeader,HtmlTableFooter和HtmlTableBody部分是行的分组。最多可以有一个页眉和一个页脚,但可能有多个主体。它们中的每一个都包含可以通过getRows()访问的行

HtmlTableHeader header = table.getHeader();
List<HtmlTableRow> headerRows = header.getRows();

HtmlTableFooter footer = table.getFooter();
List<HtmlTableRow> footerRows = footer.getRows();

for (HtmlTableBody body : table.getBodies()) {
    List<HtmlTableRow> rows = body.getRows();
   
}

每个表可以可选地具有描述它的字幕元素。

String caption = table.getCaptionText()

使用框架:

示例1

通过使用HtmlPage.getFrames(),可以在<frame>元素或<iframe>元素中获取页面。
假设你有以下页面:

<html>
  <body>
    <iframe src="two.html">
  </body>
</html>

您可以使用以下代码获取two.html的内容:

List<FrameWindow> window = page.getFrames();
HtmlPage pageTwo = (HtmlPage) window.get(0).getEnclosedPage();

示例2

另一个导航API文档以获取类的所需页面的示例:

WebClient client = new WebClient();
HtmlPage mainPage = client.getPage("http://htmlunit.sourceforge.net/apidocs/index.html");

要获取第一帧的页面(左上角),然后单击第六个链接:

HtmlPage packageListPage = (HtmlPage) mainPage.getFrames().get(0).getEnclosedPage();
packageListPage.getAnchors().get(5).click();

要获取名为“packageFrame”的框架的页面(位于左下方),然后单击第二个链接:

HtmlPage pakcagePage = (HtmlPage) mainPage.getFrameByName("packageFrame").getEnclosedPage();
pakcagePage.getAnchors().get(1).click();

要获取名为“classFrame”的框架的页面(右侧):

HtmlPage classPage = (HtmlPage) mainPage.getFrameByName("classFrame").getEnclosedPage();

使用Window

所有页面都包含在WebWindow对象中。这可以是表示实际浏览器窗口的TopLevelWindow,表示<frame>元素的HtmlFrame或表示<iframe>元素的HtmlInlineFrame。

当首次实例化WebClient时,会自动创建TopLevelWindow。您可以将其视为Web浏览器显示的第一个窗口。调用WebClient.getPage(WebWindow,WebRequest)会将新页面加载到此窗口中。

JavaScript open()函数可用于将页面加载到其他窗口中。此功能将自动创建新的WebWindow对象。

WebWindowEvents

如果希望在Windows创建或页面加载时收到通知,则需要通过WebClient.addWebWindowListener(WebWindowListener)方法向WebClient注册WebWindowListener。

当通过JavaScript或WebClient打开窗口时,WebWindowEvent将被触发并传递到WebWindowListener.webWindowOpened(WebWindowEvent)方法中。请注意,事件中的新旧页面将为null,因为此时窗口中没有加载任何内容。如果在创建窗口期间指定了一个URL,则页面将被加载,另一个事件将被触发,如下所述。

当新页面加载到特定的窗口中时,WebWindowEvent将被触发并传递到WebWindowListener.webWindowContentChanged(WebWindowEvent)方法中。

使用JavaScript

介绍

我们得到的一个常见问题是“我如何测试我的JavaScript?”。没有什么真正具体使用JavaScript,它被自动处理。所以,你只需要.getPage(),找到要单击()的元素,然后检查结果。HtmlUnit测试基础中包含复杂JavaScript库的测试,您可以在这里找到它  这对于获取想法是有用的。

通常,你应该wait()或sleep()有一点,因为HtmlUnit可以在从服务器检索到AJAX响应之前完成,请阅读这个FAQ

以下是一些例子:

示例:使用Document.write()

让我们说,我们有一个包含JavaScript的页面,它将动态地将内容写入页面。以下html将动态生成五个文本框,并将它们放在表格中。每个文本框都将通过将索引附加到字符串“textfield”创建的唯一名称。

<html><head><title>Table sample</title></head><body>
    <form action='/foo' name='form1'>
    <table id="table1">
        <script type="text/javascript">
            for (i = 1; i <= 5; i++) {
                document.write("<tr><td>" + i
                    + "</td><td><input name='textfield" + i
                    + "' type='text'></td></tr>");
            }
        </script>
    </table></form>
</body></html>

我们可能想测试五个文本字段是否被创建,以便我们可以从这开始。

@Test
public void documentWrite() throws Exception {
    final WebClient webClient = new WebClient();

    final HtmlPage page = webClient.getPage("http://myserver/test.html");
    final HtmlForm form = page.getFormByName("form1");
    for (int i = 1; i <= 5; i++) {
        final String expectedName = "textfield" + i;
        Assert.assertEquals(
            "text", 
            form.<HtmlInput>getInputByName(expectedName).getTypeAttribute());
    }
}

我们也可能要确保它不会创建“textfield0”或“textfield6”来检查一个一个的错误。尝试获取不存在的元素将导致抛出异常,所以我们可以将其添加到上一个测试的结尾。

try {
    form.getInputByName("textfield0");
    fail("Expected an ElementNotFoundException");
}
catch (final ElementNotFoundException e) {
    // Expected path
}

try {
    form.getInputByName("textfield6");
    fail("Expected an ElementNotFoundException");
}
catch (final ElementNotFoundException e) {
    // Expected path
}

示例:看“警报”

通常你想观看由JavaScript触发的警报。

<html><head><title>Alert sample</title></head>
<body onload='alert("foo");'>
</body></html>

警报由AlertHandler跟踪,每当调用JavaScript alert()函数时,它将被调用。在下面的测试中,我们注册一个警报处理程序,它将所有消息保存到列表中。当页面加载完成后,我们将收集的警报列表与预期警报的另一个列表进行比较,以确保它们相同。

@Test
public void alerts() throws Exception {
    final WebClient webClient = new WebClient();

    final List collectedAlerts = new ArrayList();
    webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts));

    // Since we aren't actually manipulating the page, we don't assign
    // it to a variable - it's enough to know that it loaded.
    webClient.getPage("http://tciludev01/test.html");

    final List expectedAlerts = Collections.singletonList("foo");
    Assert.assertEquals(expectedAlerts, collectedAlerts);
}

提示,确认和状态行消息

处理提示对话框,确认对话框和状态行消息的工作方式与警报相同。您注册一个适当类型的处理程序,并在调用该方法时收到通知。有关这些的详细信息,请参阅WebClient.setPromptHandler(),WebClient.setConfirmHandler()和WebClient.setStatusHandler()。

事件处理程序

大多数事件处理程序已经实现:onload,onclick,ondblclick,onmouseup,onsubmit,onreadystatechange,...它们将在适当的时候触发,就像在“真正的浏览器”中一样。

如果您希望测试的事件尚未被支持,那么您可以通过ScriptEngine直接调用它。请注意,虽然脚本引擎是可公开访问的,但我们不建议直接使用它,除非您没有其他选择。通过点击元素并转移焦点,操作页面会更好。

使用ActiveX:

 

虽然HtmlUnit是一个模拟浏览器的纯Java实现,但在某些情况下,特定于平台的功能需要集成其他库,ActiveX是其中之一。

Windows上的Internet Explorer可以运行任意ActiveX组件(如果用户信任网站,则安全级别有目的降低)。HtmlUnit和Internet Explorer都不能控制运行ActiveX的行为,所以在使用该功能之前必须要小心。

 

当前的实现取决于Jacob,并且由于它具有.dll依赖关系,所以没有上传到maven仓库。依赖是可选的,即Jacob jar不需要编译或通常使用HtmlUnit。

要使用Jacob,请将jacob.jar添加到类路径中,并将.dll放在路径(java.library.path)中,以便以下代码适用于您:

ActiveXComponent activeXComponent = new ActiveXComponent("InternetExplorer.Application");
boolean busy = activeXComponent.getProperty("Busy").getBoolean();
System.out.println(busy);

允许HtmlUnit使用ActiveX

唯一需要的是设置WebClient属性:

webClient.getOptions().setActiveXNative(true);

 

© 著作权归作者所有

共有 人打赏支持
诺岚
粉丝 0
博文 87
码字总数 143206
作品 0
广州
程序员
模拟浏览器的神器 - HtmlUnit

随着Web的发展,RIA越来越多,JavaScript和Complex AJAX Libraries给网络爬虫带来了极大的挑战,解析页面的时候需要模拟浏览器执行JavaScript才能获得需要的文本内容。 好在有一个Java开源项...

杨尚川
2014/04/04
0
6
HtmlUnit 网络爬虫 菜鸟的学习笔记(一)

什么是HtmlUnit HtmlUnit是一个开源的浏览器模拟工具,可以方便我们模拟浏览器的行为,例如打开网页,提交表单等,这样我们可以用他来爬网页 官网下载:http://htmlunit.sourceforge.net/ ja...

木有芒果
2015/08/31
0
0
Burp Xss Scanner插件开发思路分享(附下载)

  *本文原创作者:lufei,本文属FreeBuf原创奖励计划,未经许可禁止转载   0×00 前言   Burp虽然自带xss检测,但是Pyload与数量都不是自己能掌控的。所以自己写一款Xss检测插件,对一...

FreeBuf
05/12
0
0
使用Goodcrawler爬取700集的柯南

优酷在剧集太多时通过js生成剧集列表,而要获取其播放地址则需要点击来获取。gc使用htmlunit模拟了点击动作,可以轻易的获取全部播放地址。 以下是优酷动漫的配置: <?xml version="1.0" en...

shenbaise
2014/01/14
0
3
selenium之WebDriver

1、什么情况下选用WebDriver? (1)Selenium-1.0不支持的浏览器功能。 (2)multiple frames, multiple browser windows, popups, and alerts. (3)页面导航。 (4)下拉。 (5)基于AJAX的...

李长春
2011/07/20
0
3
HtmlUnit 网络爬虫 菜鸟的学习笔记(二)

这次我以爬新浪微博为例,这个过程太纠结了,参考了好多大神的帖子,不过还是遗留了很多问题,我们慢慢来看,希望大神帮于指正,我的方法暂时来说还是比较挫的 登陆问题 爬新浪微博首先要登陆...

木有芒果
2015/09/01
0
1
scrapy实战之定向抓取某网店商品资料

网络爬虫(web crawler)又称为网络蜘蛛(web spider)是一段计算机程序,它从互联网上按照一定的逻辑和算法抓取和下载互联网的网页,是搜索引擎的一个重要组成部分。一般的爬虫从一部分start...

索隆
2013/04/09
0
0
如何在无显示器的ubuntu下跑前端测试

翻译自:http://www.installationpage.com/selenium/how-to-run-selenium-headless-firefox-in-ubuntu/ Selenium是一个web自动化测试框架。用它可以实现web应用自动化测试。不过,我不只是用...

翟志军
2014/07/27
0
11
模拟ajax实现网络爬虫——HtmlUnit

最近在用Jsoup抓取某网站数据,可有些页面是ajax请求动态生成的,去群里问了一下,大神说模拟ajax请求即可。去网上搜索了一下,发现了这篇文章,拿过来先用着试试。转帖如下: 网上关于网络爬...

MiniBu
2013/06/26
0
4
Selenium 1.0 vs Selenium 2.0 (Selenium Web-driver)

Selenium is browser automation tool, for more information select thislink. We already have Selenium1.0, why Selenium2.0? Selenium1.0 can't tackle following items. 1. Native keyb......

李长春
2011/07/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

shell中的函数、shell中的数组、告警系统需求分析

shell中的函数 格式: 格式: function f_name() { command } 函数必须要放在最前面 示例1(用来打印参数) 示例2(用于定义加法) 示例3(用于显示IP) shell中的数组 shell中的数组1 定义数...

Zhouliang6
27分钟前
1
0
用 Scikit-Learn 和 Pandas 学习线性回归

      对于想深入了解线性回归的童鞋,这里给出一个完整的例子,详细学完这个例子,对用scikit-learn来运行线性回归,评估模型不会有什么问题了。 1. 获取数据,定义问题     没有...

wangxuwei
48分钟前
0
0
MAC安装MAVEN

一:下载maven压缩包(Zip或tar可选),解压压缩包 二:打开终端输入:vim ~/.bash_profile(如果找不到该文件新建一个:touch ./bash_profile) 三:输入i 四:输入maven环境变量配置 MAVEN_HO...

WALK_MAN
今天
0
0
33.iptables备份与恢复 firewalld的9个zone以及操作 service的操作

10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 10.21 firewalld关于zone的操作 10.22 firewalld关于service的操作 10.19 iptables规则备份和恢复: ~1. 保存和备份iptables规则 ~2...

王鑫linux
今天
1
0
大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
今天
0
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
今天
2
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
今天
1
0
Java IO类库之BufferedInputStream

一、BufferedInputStream介绍 /** * A <code>BufferedInputStream</code> adds * functionality to another input stream-namely, * the ability to buffer the input and to * sup......

老韭菜
今天
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
0
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部