简体   繁体   English

HTMLUnit:更改用户代理字符串

[英]HTMLUnit: change User Agent string

I'm using HtmlUnit in my Java project in order to test a web page that has got Javascript inside.我在我的 Java 项目中使用 HtmlUnit 来测试一个包含 Javascript 的网页。 My code clicks a button that calls a Javascript function, wich redirect the user to another page (like link shortener services).我的代码单击一个调用 Javascript 函数的按钮,将用户重定向到另一个页面(如链接缩短服务)。 This is the code:这是代码:

public void click()
{
    WebClient webClient = new WebClient();
    HtmlPage page = webClient.getPage("http://mywebsite.com");
    HtmlImage a = page.getHtmlElementById("my_button");
    page = (HtmlPage) a.click();
}

The problem is that HTMLUnit uses the default User Agent (Internet Explorer 8) and there are a only few to set (Firefox 17 and Chrome).问题是 HTMLUnit 使用默认的用户代理(Internet Explorer 8),并且只有少数需要设置(Firefox 17 和 Chrome)。 The behavior of mywebsite.com doesn't change if it detects another browser/user agent.如果 mywebsite.com 检测到另一个浏览器/用户代理,它的行为不会改变。 By the way, the user agent string is stored by the website for statistical purposes and I need to change it every time I visit it.顺便说一句,用户代理字符串由网站存储用于统计目的,我每次访问时都需要更改它。

I've tried to change the User Agent by creating a new BrowserVersion object in this way:我试图通过以这种方式创建一个新的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);

By the way, when I instantiate a Webclient object passing my bv object, my code doesn't work anymore.顺便说一句,当我实例化传递我的bv对象的 Webclient 对象时,我的代码不再起作用。 From what I've understood, HtmlUnit documentation says that I've got to check if the user agent specified in my BrowserVersion has proper features to run Javascript.据我所知,HtmlUnit 文档说我必须检查我的 BrowserVersion 中指定的用户代理是否具有运行 Javascript 的适当功能。

However, note that the constants are not enough to fully customize the browser, you also need to look into the BrowserVersionFeatures and the classes inside "javascript" package.但是,请注意,常量不足以完全自定义浏览器,您还需要查看 BrowserVersionFeatures 和“javascript”包中的类。

What does it mean?这是什么意思? Why HtmlUnit doesn't work anymore?为什么 HtmlUnit 不再起作用? My goal is only to change the User Agent string.我的目标只是更改用户代理字符串。 How can I achieve this?我怎样才能做到这一点? Note that I've tried Selenium too, without success.请注意,我也尝试过 Selenium,但没有成功。 Thank you for your help.谢谢您的帮助。

EDIT 1:编辑 1:

Found this trick.发现了这个技巧。 If I instantiate the BrowserVersion as follow:如果我按如下方式实例化 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);

it works, but I don't understand WHY.它有效,但我不明白为什么。 I have to set the first string as Netscape (tried Chrome and Mozilla but it doesn't work).我必须将第一个字符串设置为 Netscape(尝试过 Chrome 和 Mozilla,但它不起作用)。 The 2nd string is random, I can put anything if Netscape is set as first parameter.第二个字符串是随机的,如果将 Netscape 设置为第一个参数,我可以放任何东西。 The third string is the well formatted User Agent and the 4th parameter is an integer indicating the version.第三个字符串是格式良好的用户代理,第四个参数是一个表示版本的整数。 Can you explain me why it works only if Netscape is passed as first parameter and random to others (except the 2nd)?你能解释一下为什么只有当Netscape作为第一个参数并随机传递给其他参数时它才有效(第二个除外)?

UPDATES:更新:

Sometimes it doesn't work (as described above).有时它不起作用(如上所述)。 For some User Agents strings, the page is not correctly loading.对于某些用户代理字符串,页面未正确加载。 I cannot understand why the User Agent should modify the behaviour of HtmlUnit as I'm pretty sure that Javascript it's quite easy and should be run by all browser versions.我不明白为什么用户代理应该修改 HtmlUnit 的行为,因为我很确定 Javascript 它很容易并且应该由所有浏览器版本运行。 So, my final question is: how can I change the user agent string in HtmlUnit without altering its behaviour when executing Javascript?所以,我的最后一个问题是:如何在执行 Javascript 时更改 HtmlUnit 中的用户代理字符串而不改变其行为?

Using Htmlunit 2.28 you can set it like this example below使用 Htmlunit 2.28 你可以像下面这个例子一样设置它

final BrowserVersion myChrome = new BrowserVersion.BrowserVersionBuilder(BrowserVersion.CHROME)
    // do your setup here
    .setXXX(..)
    .build();

You can pass it to the WebClient constructor:您可以将其传递给WebClient构造函数:

WebClient webClient = new WebClient(BrowserVersion.CHROME);

Supported user agents are listed here: http://htmlunit.sourceforge.net/apidocs/com/gargoylesoftware/htmlunit/BrowserVersion.html此处列出了支持的用户代理: http : //htmlunit.sourceforge.net/apidocs/com/gargoylesoftware/htmlunit/BrowserVersion.html

Don't worry about creating a new BrowserVersion object.不要担心创建一个新的BrowserVersion对象。 You can change the user agent after creating the driver without messing with all the versioning mess:您可以在创建驱动程序后更改用户代理,而不会弄乱所有版本控制:

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");

This will correctly visit http://facebook.com and get redirected to https://m.facebook.com/?_rdr&refsrc=https://www.facebook.com/ because the user agent string tells facebook the browser is an iPhone.这将正确访问http://facebook.com并被重定向到https://m.facebook.com/?_rdr&refsrc=https://www.facebook.com/因为用户代理字符串告诉 facebook 浏览器是 iPhone .

On the Selenium 3 you can do:在 Selenium 3 上,您可以执行以下操作:

val browser = BrowserVersionBuilder(BrowserVersion.CHROME).build()
val driver = HtmlUnitDriver(browser);

The BrowserVersionBuilder brings a lot of customizations. BrowserVersionBuilder带来了很多自定义。

I was able to set the user agent to a random string such as 'Selenium' when constructing the Chrome Driver object.在构建 Chrome Driver 对象时,我能够将用户代理设置为随机字符串,例如“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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM