使用JSoup转到aspx表单上的下一页

时间:2018-06-26 17:00:10

标签: java android jsoup

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

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

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

一旦转到下一页,我还需要更新结果。

// 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

谢谢。

2 个答案:

答案 0 :(得分:1)

这不是Jsoup的工作! Jsoup是一个解析器,具有一个不错的DOM API,可让您处理狂野的HTML,就好像它的格式正确且不受错误和废话的束缚。 >

在特定情况下,您可以直接通过找到链接并递归检索HTML页面,从应用中抓取。像

MongoDBPipeline

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

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

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

答案 1 :(得分:1)

在ASPX上分页可能会很痛苦。最好的办法是使用浏览器查看发送到服务器的数据参数,然后尝试在代码中进行仿真。

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

简而言之,您应该尝试使用<form>获取一个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);

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

希望这会有所帮助。