2011-06-06 143 views
2

我在运行Google Apps脚本的Google协作平台页面上有一个链接。当我手动点击Firefox中的链接时,它工作正常。如何从HtmlUnit运行Google Apps脚本?

当我使用HtmlUnit进行相同操作时,一切似乎都正常。使用HtmlUnit,我可以登录(运行Google Apps脚本时必须登录),进入网页,确定链接并点击链接,但脚本无法运行。

代码的胆量很简单:

WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6); 
HtmlPage page = webClient.getPage("https://sites.google.com/site/mywebpage"); 
HtmlAnchor anchor = page.getAnchorByName("MyAnchor"); 
anchor.click(); 

所以缺什么,或者我做错了什么?

我创建的网页与原文链接:

<a href="/macros/sites?action=run&lib=094bahv51120b3d65&funcName=MyFunctionName" name="MyAnchor">Click here to run function</a> 

在保存网页编辑,谷歌网站会自动把它改为:

<a href="#" name="MyAnchor" class="apps-script-run-link" id="ACiQKe2HyNeo..etc...01120b3d65#MyFunctionName">Click here to run function</a> 

click()不工作,因为它的作用在现在只是“#”而不是链接定义的href属性上? 或者HtmlUnit对JavaScript(Mozilla Rhino)的语言支持是否不正确地执行Javascript来处理点击的链接(这意味着我需要用能够在Google Sites网页中识别Javascript的东西来替代Rhino)? 还是我犯的一些其他基本错误?

我迷路了,所以任何帮助非常感谢!

UPDATE

我跟着你的建议,罗德尼,发现问题并不注销谷歌网站。单击链接执行脚本后,使用HtmlUnit单击“注销”链接,使脚本运行正常。唯一的问题是它带来了以下错误(不停止脚本运行):

SEVERE: Job run failed with unexpected RuntimeException:
TypeError: Cannot set property "innerHTML" of null to "Finished script: Finished script MyFunctionName"

更新2

现在已经解决了这个概率了。没有足够的时间让脚本在完成注册之前完成。加上这个固定它:

webClient.waitForBackgroundJavaScriptStartingBefore(5000); 

非常感谢您的帮助,罗德尼 - 和纳文的良好编辑!

回答

0

它在Firefox中工作吗?如果是这样,问题可能是htmlunit本身,这不是一个真正的浏览器。尝试使用Watir或iMacros代替。

+0

是的,在Firefox中工作正常。但是我需要从正在执行的Java程序中触发Google Apps脚本的运行。 HtmlUnit允许您通过几个简单的调用来完成此操作。我可以使用Watir或IMacros做到这一点吗? – Marty 2011-06-06 23:33:53

0

HtmlUnit具有相当不错的Javascript支持,所以我怀疑这是问题所在。

你怎么知道脚本没有运行?或者更好的是,如果脚本已经成功运行,您如何从HtmlUnit的角度知道?当你点击FF中的链接时,你大概会看到一些事情发生。您依赖于人类视觉和浏览器供人类使用。使用HtmlUnit,您需要指示您的代码“查看”相同的结果,无论是通过检查随后的DOM树,还是处理弹出窗口或任何需要的内容。这在思维上有点转变。

你的脚本是做什么的?操作页面的内容?打开一个对话框?重定向到另一个页面? HtmlUnit会自动处理一些事情,有些(如打开对话框)需要处理程序定义。

+0

罗德尼,非常感谢您的回复。 – Marty 2011-06-08 22:37:02

+0

是的,脚本修改了另一个网页的内容。通过在事件发生后在Firefox中查看页面,很容易检查脚本是否从HtmlUnit运行。有没有什么方法可以知道HtmlUnit中的click(),除了检查链接跳转到的页面click()函数的返回之外呢?由于click()只会触发脚本函数,因此返回的Web页面与当前页面相同,所以这并不能告诉我发生了什么。你认为我需要一些额外的处理程序来做我想做的事吗? – Marty 2011-06-08 22:52:28

+0

啊......“返回的网页和现在的一样”不太正确。它是“HtmlPage”的同一个实例,但是如果你的click()JS代码实际上改变了页面DOM,它的内容将被页面上的任何Javascript更新。最坏的情况是,在调用click()之前和之后在页面对象上调用asXml();理想情况下,你遍历DOM寻找特定的变化。 – 2011-06-08 22:59:30