Chung
Hầu như tất cả các trình phân tích cú pháp HTML đã biết đều triển khai API W3C DOM (một phần của API JAXP, API Java để xử lý XML) và cung cấp cho bạn một bản org.w3c.dom.Document
sao sẵn sàng để sử dụng trực tiếp bởi API JAXP. Sự khác biệt chính thường được tìm thấy trong các tính năng của trình phân tích cú pháp được đề cập. Hầu hết các trình phân tích cú pháp ở một mức độ nhất định tha thứ và khoan dung với HTML không được định dạng tốt ("tagsoup"), như JTidy , NekoHTML , TagSoup và HtmlCleaner . Bạn thường sử dụng loại trình phân tích cú pháp HTML này để "dọn dẹp" nguồn HTML (ví dụ: thay thế hợp lệ HTML bằng hợp lệ <br>
XML <br />
), để bạn có thể duyệt qua "cách thông thường" bằng cách sử dụng API W3C DOM và JAXP.
Những người duy nhất nhảy ra là HtmlUnit và Jsoup .
HtmlUnit
HtmlUnit cung cấp API hoàn toàn riêng mang đến cho bạn khả năng hoạt động như một trình duyệt web theo chương trình. Tức là nhập giá trị biểu mẫu, nhấp vào các phần tử, gọi JavaScript, vân vân. Nó không chỉ đơn thuần là một trình phân tích cú pháp HTML. Đây là một "công cụ kiểm tra đơn vị web" không có GUI "và HTML thực sự.
Jsoup
Jsoup cũng cung cấp một API hoàn toàn riêng. Nó cung cấp cho bạn khả năng chọn các phần tử bằng cách sử dụng các bộ chọn CSS giống như jQuery và cung cấp API khéo léo để duyệt qua cây DOM HTML để có được các phần tử quan tâm.
Đặc biệt là việc duyệt qua cây HTML DOM là thế mạnh chính của Jsoup. Những người đã từng làm việc với họ org.w3c.dom.Document
biết thế nào là đau đớn khi vượt qua DOM bằng cách sử dụng verbose NodeList
và Node
API. Đúng, XPath
làm cho cuộc sống dễ dàng hơn, nhưng vẫn là một đường cong học tập khác và cuối cùng nó có thể vẫn còn dài dòng.
Đây là một ví dụ sử dụng trình phân tích cú pháp W3C DOM "đơn giản" như JTidy kết hợp với XPath để trích đoạn đầu tiên của câu hỏi của bạn và tên của tất cả người trả lời (Tôi đang sử dụng XPath vì không có nó, mã cần thiết để thu thập thông tin quan tâm mặt khác sẽ lớn lên gấp 10 lần, mà không cần viết các phương thức tiện ích / trợ giúp).
String url = "http://stackoverflow.com/questions/3152138";
Document document = new Tidy().parseDOM(new URL(url).openStream(), null);
XPath xpath = XPathFactory.newInstance().newXPath();
Node question = (Node) xpath.compile("//*[@id='question']//*[contains(@class,'post-text')]//p[1]").evaluate(document, XPathConstants.NODE);
System.out.println("Question: " + question.getFirstChild().getNodeValue());
NodeList answerers = (NodeList) xpath.compile("//*[@id='answers']//*[contains(@class,'user-details')]//a[1]").evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < answerers.getLength(); i++) {
System.out.println("Answerer: " + answerers.item(i).getFirstChild().getNodeValue());
}
Và đây là một ví dụ về cách thực hiện chính xác như vậy với Jsoup:
String url = "http://stackoverflow.com/questions/3152138";
Document document = Jsoup.connect(url).get();
Element question = document.select("#question .post-text p").first();
System.out.println("Question: " + question.text());
Elements answerers = document.select("#answers .user-details a");
for (Element answerer : answerers) {
System.out.println("Answerer: " + answerer.text());
}
Bạn có thấy sự khác biệt? Nó không chỉ ít mã hơn, mà Jsoup cũng tương đối dễ nắm bắt nếu bạn đã có kinh nghiệm vừa phải với các bộ chọn CSS (ví dụ: phát triển trang web và / hoặc sử dụng jQuery).
Tóm lược
Những ưu và nhược điểm của mỗi nên đủ rõ ràng bây giờ. Nếu bạn chỉ muốn sử dụng API JAXP tiêu chuẩn để duyệt qua nó, thì hãy tìm nhóm trình phân tích cú pháp được đề cập đầu tiên. Có khá nhiều trong số họ. Lựa chọn nào tùy thuộc vào các tính năng mà nó cung cấp (việc dọn dẹp HTML có dễ dàng với bạn không? Có một số trình nghe / chặn và trình dọn dẹp dành riêng cho thẻ không?) Và độ mạnh của thư viện (mức độ thường xuyên được cập nhật / bảo trì / sửa lỗi? ). Nếu bạn muốn đơn vị kiểm tra HTML, thì HtmlUnit là cách để đi. Nếu bạn muốn trích xuất dữ liệu cụ thể từ HTML (thường là yêu cầu trong thế giới thực), thì Jsoup là cách để đi.