我正尝试使用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
谢谢。
答案 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);
将从每个响应中获取更多数据参数。但是很大程度上取决于您要定位的网站。
希望这会有所帮助。