13

我需要做的是浏览到一个网页,登录,然后浏览到该站点上需要您登录的另一个网页,因此它需要保存 cookie。之后,我需要单击该页面上的一个元素,我将在其中填写表单并获取网页返回给我的消息。我需要实际转到页面并单击按钮(假设只是直接导航到链接)的原因是因为每次登录并单击链接时都会为您分配一个会话 ID,而且它总是不同的。该按钮看起来像这样,它不是普通的 href 链接:

<span id=":tv" idlink="" class="sA" tabindex="0" role="link">Next</span>

无论如何,最简单的方法是什么?谢谢。

更新:在尝试了 HTMLunit 和其他无头浏览器库之后,似乎没有使用任何“无头”。我最近发现的关于这个页面的另一件事是,所有的 HTML 都是一些奇怪的格式......它都在一个脚本标签中。这是一个示例。

"?ui\x3d2\x26view\x3dss\x26mset\x3dmain\x26ver\x3d-68igm85d1771\x26am\x3d!Zsl-0RZ-XLv0BO3aNKsL0sgMg3nH10t5WrPgJSU8CYS-KNWlyrLmiW3HvC5ykER_n_5dDw\x26fri"],"http://example.com/?ctx\x3d%67mail\x26hl\x3den",,0,"Gmail","Gmail",[["us","c130f0854ca2c2bb",[["n"],["m","New features!"],["u"],["k","0"],["p","1000:500000,10,200000,5,100000,3,75000,2,0,1"],["h","https://survey.googleratings.com/wix/p1679258.aspx?l\x3d1033"],["at","query,5,contacts,5,adv,5,cf,5,default,20"],["v","https://www.youtube.com/embed/Ra8HG6MkOXY?showinfo\x3d0"],

当我检查按钮上的元素时,我在上面为按钮发布的 HTML 代码会出现,但在查看源代码时不会出现。基本上,我需要做的是使用某种 GUI 并让用户导航到链接,然后让程序填写信息。有谁知道我该怎么做?谢谢。

4

6 回答 6

5

查看 Selenium 的 5 分钟入门指南:http ://code.google.com/p/selenium/wiki/GettingStarted

于 2013-02-09T05:09:47.623 回答
2

在登录页面上,查看表单的 HTML 以查看它发布到的 url 和 url 参数。然后用正确的信息填充相同的参数请求该 url,并确保保存所有 cookie 标头以发送到第二页。然后使用 html 解析器找到您的链接。sourceforge 上有几个 html 解析器可用,您甚至可以尝试 java 内置的 xml 解析器,但如果站点有一个很小的 ​​html 错误,它们就会出现故障。

编辑没有注意到它不是正常链接的事实。在这种情况下,您需要查看网站的 javascript 以查看链接指向的位置。如果链接需要运行 javascript,它会变得更加复杂。Java 无法执行浏览器 javascript,但我发现了一个名为 DJ native swing 的库,其中包含一个可以添加到 jframes 的 Web 浏览器类。它使用您的本机浏览器来呈现和运行 javascript。

于 2013-02-06T23:36:05.783 回答
1

正如其他人所指出的,这在 Selenium 中应该是可能的。

我使用 Selenium 登录然后爬取一个站点并发现站点上每个表单(30 多个表单)的每个值的排列。这些值稍后用于填写和提交具有特定值排列的表单。这个站点非常重 JS/jQuery,我使用 Selenium 对 javascript 执行器、css 选择器和 XPath 的内置支持来实现这一点。

我将 HtmlUnit 和 HttpUnit 实现为更快的替代方案,但鉴于我正在抓取的网站的 JS 语义,我发现它们不如 Selenium 可靠。

很难为您提供有关如何完成它的代码,因为您的 Selenium 实现将是非常特定于页面的,我无法查看您正在编码的页面来弄清楚该按钮脚本垃圾发生了什么。但是,我包含了一些可能相关的硒代码(Java)片段:

Element element = driver.findElements(By.id(value)); //find element on page
List<Element> buttons = parent.findElements(By.xpath("./tr/td/button")); //find child element
button.click();
element.submit() //submit enclosing form
element.sendKeys(text); //enter text in an input
String elementText = (String) ((JavascriptExecutor) driver).executeScript("return arguments[0].innerText || arguments[0].textContent", element); //interact with a selenium element via JS

如果您在不同页面上编写类似的功能,那么接口后面的PageObjects可以提供帮助。

Anew 发布的链接是一个很好的起点,而且 StackOverflow 可以解决几乎所有 Selenium 问题。

于 2013-02-16T00:15:41.643 回答
0

与其尝试以编程方式浏览,不如尝试执行登录请求并保存 cookie,然后在下一个请求中将它们设置为表单帖子。

于 2013-02-09T07:10:31.950 回答
0

HTMLUnit 在处理 JavaScript 方面非常糟糕,Rhino JS 库经常产生错误(实际上没有错误是例外)。我建议使用Selenium,它基本上是一个控制无头浏览器(基于 chrome、firefox)的框架。

对于您的问题,以下代码可以完成工作

selenium.open(myurl);
selenium.click("id=:tv");

然后,您必须等待页面加载

selenium.waitForPageToLoad(someTime);
于 2013-02-15T07:41:33.370 回答
0

我会在任何一天推荐 htmlunit。这是一个很棒的图书馆。

首先,查看他们的网页 ( http://htmlunit.sourceforge.net/ ) 以启动和运行 htmlunit。确保使用最新的快照(写这篇文章时是 2.12)

尝试这些设置几乎可以忽略任何障碍:

WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getCookieManager().setCookiesEnabled(true);

然后在获取页面时,确保在对页面进行任何操作之前等待后台 Javascript,例如发布登录表单:

//Get Page
HtmlPage page1 = webClient.getPage("https://login-url/");

//Wait for background Javascript
webClient.waitForBackgroundJavaScript(10000);

//Get first form on page
HtmlForm form = page1.getForms().get(0);

//Get login input fields using input field name
HtmlTextInput userName = form.getInputByName("UserName");
HtmlPasswordInput password = form.getInputByName("Password");

//Set input values
userName.setValueAttribute("MyUserName"); 
password.setValueAttribute("MyPassword"); 

//Find the first button in form using name, id or xpath
HtmlElement button = (HtmlElement) form.getFirstByXPath("//button");

//Post by clicking the button and cast the result, login arrival url, to a new page and repeat what you did with page1 or something else :) 
HtmlPage page2 = (HtmlPage) button.click(); 

//Profit
System.out.println(page2.asXml());    

我希望这个基本示例对您有所帮助!

于 2013-02-15T23:28:33.017 回答