我在我的Java项目中使用HtmlUnit来测试一个内部有Javascript的网页。我的代码点击一个调用Javascript函数的按钮,将用户重定向到另一个页面(如链接缩短服务)。这是代码:
public void click()
{
WebClient webClient = new WebClient();
HtmlPage page = webClient.getPage("http://mywebsite.com");
HtmlImage a = page.getHtmlElementById("my_button");
page = (HtmlPage) a.click();
}
问题是HTMLUnit使用默认的用户代理(Internet Explorer 8),并且只有少数设置(Firefox 17和Chrome)。如果检测到另一个浏览器/用户代理,mywebsite.com的行为不会更改。顺便说一句,网站存储用户代理字符串用于统计目的,每次访问时我都需要更改它。
我尝试通过以这种方式创建新的BrowserVersion
对象来更改用户代理:
BrowserVersion bv = new BrowserVersion("Chrome", "Mozilla/5.0", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36", 28);
顺便说一下,当我实例化一个传递我的bv
对象的Webclient对象时,我的代码不再起作用了。根据我的理解,HtmlUnit文档说我必须检查我的BrowserVersion中指定的用户代理是否具有运行Javascript的正确功能。
但请注意,常量不足以完全自定义 浏览器,你还需要查看BrowserVersionFeatures和 “javascript”包中的类。
这是什么意思?为什么HtmlUnit不再起作用?我的目标只是更改用户代理字符串。我怎样才能做到这一点?请注意,我也尝试过Selenium,但没有成功。 谢谢你的帮助。
编辑1:
发现了这个伎俩。如果我实例化BrowserVersion如下:
BrowserVersion bv = new BrowserVersion("Netscape", "blablabla", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36", 0);
它有效,但我不明白为什么。我必须将第一个字符串设置为Netscape(尝试过Chrome和Mozilla,但它不起作用)。第二个字符串是随机的,如果将Netscape设置为第一个参数,我可以放任何东西。第三个字符串是格式良好的用户代理,第四个参数是指示版本的整数。你能解释一下为什么只有当Netscape
作为第一个参数传递并随机传递给其他参数(第二个除外)时它才有效吗?
更新
有时它不起作用(如上所述)。对于某些用户代理字符串,页面未正确加载。我无法理解为什么用户代理应该修改HtmlUnit的行为,因为我很确定Javascript它很容易并且应该由所有浏览器版本运行。所以,我的最后一个问题是:如何在不改变执行Javascript时的行为的情况下更改HtmlUnit中的用户代理字符串?
答案 0 :(得分:1)
使用Htmlunit 2.28你可以像下面这个例子那样设置它
final BrowserVersion myChrome = new BrowserVersion.BrowserVersionBuilder(BrowserVersion.CHROME)
// do your setup here
.setXXX(..)
.build();
答案 1 :(得分:1)
您可以将其传递给WebClient
构造函数:
WebClient webClient = new WebClient(BrowserVersion.CHROME);
此处列出了受支持的用户代理:http://htmlunit.sourceforge.net/apidocs/com/gargoylesoftware/htmlunit/BrowserVersion.html
答案 2 :(得分:0)
有点晚了..但我找到了http://htmlunit.sourceforge.net/apidocs/com/gargoylesoftware/htmlunit/BrowserVersion.html
答案 3 :(得分:0)
不要担心创建新的BrowserVersion
对象。您可以在创建驱动程序后更改用户代理,而不会弄乱所有版本控制混乱:
String DEFAULT_MOBILE_USER_AGENT_STRING = "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25";
HtmlUnitDriver driver = new HtmlUnitDriver(); //Or insert a capabilities object
driver.getBrowserVersion().setUserAgent(DEFAULT_MOBILE_USER_AGENT_STRING);
driver.get("http://facebook.com");
这将正确访问http://facebook.com
并重定向到https://m.facebook.com/?_rdr&refsrc=https://www.facebook.com/
,因为用户代理字符串告诉Facebook浏览器是iPhone。
答案 4 :(得分:0)
构造Chrome驱动程序对象时,我能够将用户代理设置为随机字符串,例如'Selenium'。
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--start-maximized");
chromeOptions.addArguments("user-agent=Selenium");
chromeOptions.setExperimentalOption("useAutomationExtension", false);
aDriver = new ChromeDriver(chromeOptions);
aDriver.manage().timeouts().implicitlyWait(Const.Chrome_TIMEOUT, TimeUnit.SECONDS);
答案 5 :(得分:0)
在Selenium 3上,您可以执行以下操作:
val browser = BrowserVersionBuilder(BrowserVersion.CHROME).build()
val driver = HtmlUnitDriver(browser);
BrowserVersionBuilder
带来了很多定制。