【问题标题】:Going to next page on an aspx form with JSoup使用 JSoup 转到 aspx 表单的下一页
【发布时间】:2018-12-05 11:35:33
【问题描述】:

我正在尝试使用 JSoup 转到 aspx 表单的下一页。

我可以找到下一个按钮本身。我只是不知道该怎么处理它。

这个想法是,对于那个特定的表单,如果存在下一个按钮,我们将模拟一次点击并转到下一页。但是除了模拟点击之外的任何其他解决方案都可以,只要我们进入下一页。

一旦我们进入下一页,我还需要更新结果。

// Connecting, entering the data and making the first request

...

// Submitting the form
Document searchResults = form.submit().cookies(resp.cookies()).post();

// reading the data. Everything up to this point works as expected

...

// finding the next button (this part also works as expected)
Element nextBtn = searchResults.getElementById("ctl00_MainContent_btnNext");

if (nextBtn != null) {
    // click? I don't know what to do here.
    searchResults  = ??? // updating the search results to include the results from the second page
}

页面本身是www.somePage.com/someForm.aspx,所以我不能使用这里所说的解决方案:

Android jsoup, how to select item and go to next page

我找不到任何其他建议。

有什么想法吗?我错过了什么?使用 JSoup 甚至可以模拟点击吗?文档对此只字未提。但我确信人们能够浏览这些类型的表单。

另外,我正在使用 Android,所以我不能使用 HtmlUnit,如下所述:

importing HtmlUnit to Android project

谢谢。

【问题讨论】:

  • 观察 XHR 请求。检查如果单击“下一步”按钮会发生什么。
  • 参考此答案并了解单击按钮时会发生什么。 stackoverflow.com/a/4423097/8329042
  • 谢谢你们。我已经在使用它了。我只是很难隔离和理解单击下一步时会发生什么。也许这是我对检查员的经验不足:p

标签: java android jsoup


【解决方案1】:

这不是 Jsoup 的工作! Jsoup 是一个具有良好 DOM API 的解析器,它允许您处理狂野的 HTML,就好像它是格式正确的,并且不会因错误和废话而瘫痪。 p>

在您的特定情况下,您可能能够通过查找链接和递归检索 HTML 页面直接从您的应用中抓取目标网站。类似的东西

private void scrape(String url) {
  Document doc = Jsoup.connect(url).get();
  // Analyze current document content here...
  // Then continue
  for (Element link : doc.select(".ctl00_MainContent_btnNext")) {
    scrape(link.attr("href"));
  }
}

但在一般情况下,您想要做的事情需要 Jsoup 提供的更多功能:一个能够解释 HTML、CSS 和 Javascript 的用户代理,您可以从应用程序调用该 API 来模拟点击。例如硒:

WebDriver driver = new FirefoxDriver();
driver.findElement(By.name("next_page")).click();

Selenium 不能捆绑在 Android 应用中,因此我建议您将 Selenium 代码放在服务器上,并通过一些 REST API 访问它。

【讨论】:

  • 这是个好主意,但遗憾的是,这超出了我“允许”为这个项目做的事情。看起来我误解了 Jsoup 的目的。会再读一遍文档。谢谢。
  • Jsoup 可能就足够了。这一切都取决于特定的目标站点:如果它是静态 HTML Jsoup 将处理它,我为抓取例程提供了一个存根
  • 是的。我看到了。问题是我没有网址。它是 www.somePage.com/someForm.aspx,当我单击“下一步”按钮时,即使它更改了页面,URL 仍然完全相同。我知道它必须在内部进行一些更改,但我似乎无法通过检查器弄清楚什么。
  • 使用 XHR (JavaScript) 加载数据。 99% 如果没有像 Selenium 这样成熟的用户代理,你不会这样做。 ?
【解决方案2】:

在 ASPX 上分页可能会很痛苦。您可以做的最好的事情是使用您的浏览器查看它发送到服务器的数据参数,然后尝试在代码中进行模拟。

我已经写了a detailed tutorial on how to handle it here,但它使用了单一的 HTML 解析器(它是商业封闭源代码)而不是 JSoup。

简而言之,您应该尝试用id="aspnetForm" 获取<form> 元素,并读取表单元素以生成下一页的POST 请求。表单数据通常带有以下内容:

__EVENTTARGET = 
__EVENTARGUMENT = 
__VIEWSTATE = /wEPDwUKMTU0OTkzNjExNg8WBB4JU29ydE9yZ ... a very long string
__VIEWSTATEGENERATOR = 32423F7A
... and other gibberish

然后,您需要查看其中的每一项,并与您的浏览器发送的内容进行比较。有时您需要从页面的其他元素中获取值来生成类似的 POST 请求。您可能必须删除您获得的一些参数 - 再次,使您的代码行为与您的浏览器完全相同

经过一些(令人沮丧的)试验和错误后,你会得到它的工作。服务器应返回一个以竖线分隔的结果,您可以对其进行分解和解析。类似的东西:

25081|updatePanel|ctl00_ContentPlaceHolder1_pnlgrdSearchResult|
<div>
    <div style="font-weight: bold;">
        ... more stuff
|__EVENTARGUMENT||343908|hiddenField|__VIEWSTATE|/wEPDwU... another very long string ...1Pni|8|hiddenField|__VIEWSTATEGENERATOR|32423F7A| other gibberish

从那种响应中,您需要为后续页面生成新的 POST 请求,例如:

 String viewState = substringBetween(ajaxResponse, "__VIEWSTATE|", "|");

然后:

  request.setDataParameter("__VIEWSTATE", viewState);

将从每个响应中获取更多数据参数。但很大程度上取决于您的目标网站。

希望这会有所帮助。

【讨论】:

  • 完美。谢谢你的详细解释。很有帮助。
猜你喜欢
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多