使用 JSoup 转到 aspx 表单上的下一页
Going to next page on an aspx form with JSoup
我正在尝试使用 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,如下所述:
谢谢。
这不是 Jsoup 的工作! Jsoup 是一个解析器,具有很好的 DOM API 可以让你处理野生 HTML就好像它格式正确,没有错误和废话。
在您的具体情况下,您可能能够通过查找链接和检索 [=28] 直接从您的应用中 抓取 目标站点=] 页面递归。像
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.
访问
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 请求。您可能必须删除您获得的一些参数 - 再次,使您的代码的行为与您的浏览器完全相同
经过一些(令人沮丧的)试验和错误后,您会得到它的工作。服务器应该 return 一个竖线分隔的结果,您可以对其进行分解和解析。类似于:
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);
从每个响应中获取的数据参数会更多。但很大程度上取决于您定位的网站。
希望对您有所帮助。
我正在尝试使用 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,如下所述:
谢谢。
这不是 Jsoup 的工作! Jsoup 是一个解析器,具有很好的 DOM API 可以让你处理野生 HTML就好像它格式正确,没有错误和废话。
在您的具体情况下,您可能能够通过查找链接和检索 [=28] 直接从您的应用中 抓取 目标站点=] 页面递归。像
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.
访问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 请求。您可能必须删除您获得的一些参数 - 再次,使您的代码的行为与您的浏览器完全相同
经过一些(令人沮丧的)试验和错误后,您会得到它的工作。服务器应该 return 一个竖线分隔的结果,您可以对其进行分解和解析。类似于:
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);
从每个响应中获取的数据参数会更多。但很大程度上取决于您定位的网站。
希望对您有所帮助。