[英]Why JSoup does not read all the elements of the page?
今天,我開始與JSoup
一起“玩”。 我想知道JSoup
到底有多強大,所以我尋找了一個包含很多元素的網頁,然后嘗試檢索所有元素。 我找到了想要的東西: http : //www.top1000.ie/companies 。
這是一個列表,其中包含許多相似的元素(1000個)(列表的每個公司)。 只需更改其中的文本,以便我嘗試檢索的就是該文本,但是我只能獲取前20個元素,而不能獲取其余元素。
這是我的簡單代碼:
package retrieveInfo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Retrieve {
public static void main(String[] args) throws Exception{
String url = "http://www.top1000.ie/companies";
Document document = Jsoup.connect(url)
.userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
.timeout(1000*5)
.get();
Elements companies = document.body().select(".content .name");
for (Element company : companies) {
System.out.println("Company: " + company.text());
}
}
}
我雖然可能是頁面沒有時間加載,所以這就是為什么我將.timeout(1000*5)
等待5秒,但是我只能得到列表的前20個元素的原因。
JSoup
是否有可以從網頁檢索的元素限制? 我認為不應這樣做,因為它似乎是為此目的而准備的,因此我認為我的代碼中缺少某些內容。
任何幫助,將不勝感激。 提前致謝!
我查看了您要解析的網站。 問題是,站點的第一個調用僅加載了前20個comanpies。 其余通過AJAX加載。 而且Jsoup不會解釋或運行JavaScript。 您可以為此使用selenium webdriver,或者直接找出AJAX調用。
如果沒有通過maxBodySize()方法告知,則Jsoup限制為1M。 因此,您可能需要這樣做:
Document document = Jsoup.connect(url)
.userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
.maxBodySize(0)
.timeout(1000*5)
.get();
當心,以上完全關閉了大小限制。 這可能不是一個好主意,因為Jsoup在內存中構建DOM,因此您可能會遇到大型文檔的內存堆大小問題。 如果確實有這樣的問題,則可能有助於切換到另一個基於SAX的HTML解析器。
該站點最初僅加載前20個元素。 向下滾動時,腳本將加載下一個元素塊( POST
到http://www.top1000.ie/companies?page=2 )。 然后,腳本將接收到的元素添加到DOM。
但是,您從POST
獲得的對/companies?page=
的響應是JSON。
{
"worked":true,
"has_more":true,
"next_url":"/companies?page=3",
"html":"..."
...
}
此處的“ html”字段似乎包含將添加到DOM中的元素。
使用Jsoup獲取數據將是乏味的,因為Jsoup將在實際JSON周圍添加所有類型的標簽,並且還將轉義某些字符。
我認為你會使用過的方式之一更好地在這個崗位 ,連接到http://www.top1000.ie/companies?page=1並逐頁讀取數據頁。
編輯這是一個最小示例,說明如何使用HttpURLConnection
和minimal-json解析器解決此問題。
void readPage(int page) throws IOException {
URL url = new URL("http://www.top1000.ie/companies?page=" + page);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
try (OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) {
// no need to post any data for this page
writer.write("");
}
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
try (Reader reader = new InputStreamReader(connection.getInputStream())) {
String html = Json
.parse(reader)
.asObject()
.getString("html", "");
Elements companies = Jsoup
.parse(html)
.body().select(".content .name");
for (Element company : companies)
System.out.println("Company: " + company.text());
}
} else {
// handle HTTP error code.
}
}
在這里,我們使用HttpURLConnection
將POST
請求(不包含任何數據)發送到URL,使用JSON解析器從結果中獲取"html"
字段,然后使用Jsoup
對其進行Jsoup
。 只需循環調用要讀取的頁面的方法即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.