送HTTP請求:首先,你需要向目標網頁發送HTTP請求以獲取其HTML內容。這可以通過Java的內置庫java.net.HttpURLConnection或者使用更高級的庫如Apache HttpClient、OkHttp等來完成。
讀取響應內容:一旦你發送了請求并收到了響應,你需要讀取響應的內容,這通常是HTML格式的字符串。
解析HTML:然后,你需要解析HTML字符串以提取所需的信息。這可以通過正則表達式來完成,但通常建議使用專門的HTML解析庫,如Jsoup。Jsoup提供了一種非常方便的方式來解析HTML文檔,并可以通過類似于CSS或jQuery的選擇器語法來提取和操作數據。
如果你需要處理更復雜的網頁或進行更高級的網頁抓取和解析任務,你可能還需要考慮使用如Selenium這樣的瀏覽器自動化工具來模擬真實的瀏覽器行為。但是,請注意,頻繁或大規模地抓取網頁可能會違反網站的使用條款,甚至可能構成法律問題。
時候編輯器傳到后臺的內容是帶Html標簽的,或者有時候需要形成一個完整的Html文檔,也或者需要解析其中的文字(text()),Java后臺處理用Jsoup非常方便,也可以用選擇器快速獲取元素,類似于jQuery。獲取到文檔對此之后對其處理與JS處理DOM一樣方便,選取元素也類似于JS,也有類似于jQuery的語法,官方的解釋
1.最基本的解析Html字符串
@Test public void testHtmlToString2() { String html = "<p>這是一個段落<img src=\"test.img\"/>內容;</p>"; Document doc = Jsoup.parse(html); System.out.println(doc); // 輸出帶標簽的html文檔 System.out.println("---------------------\n"+doc.text()); // 輸出內容 Elements element = doc.getElementsByTag("p"); System.out.println("---------------------\n"+element.get(0).html()); }
結果:
<html> <head></head> <body> <p>這是一個段落<img src="test.img">內容;</p> </body> </html> --------------------- 這是一個段落內容; --------------------- 這是一個段落<img src="test.img">內容;
2.解析字符串
// 解析html字符串 @Test public void testHtmlToString() { String html = "<html><head><title>First parse</title></head>" + "<body><p style='center'>Parsed HTML into a doc.</p></body></html>"; Document doc = Jsoup.parse(html); System.out.println(doc); // 輸出帶標簽的html文檔 System.out.println("---------------------\n"+doc.text()); // 輸出內容 }
結果:
<html>
<head>
<title>First parse</title>
</head>
<body>
<p style="center">Parsed HTML into a doc.</p>
</body>
</html>
---------------------
First parse Parsed HTML into a doc.
3.// 解析body片段
@Test public void test2() { String html = "<div><p>Lorem ipsum.</p>"; Document doc = Jsoup.parseBodyFragment(html); System.out.println(doc); System.out.println(doc.text()); }
結果:
<html>
<head></head>
<body>
<div>
<p>Lorem ipsum.</p>
</div>
</body>
</html>
Lorem ipsum.
4.// 解析一個url與用選擇器選擇元素(相當于查看源碼)
@Test public void test4() throws IOException { Document doc = Jsoup.connect("http://qiaoliqiang.cn:8080/").get(); String title = doc.title();// 獲取title System.out.println(title); System.out.println("---------------------\n"+doc.toString()+"---------------------\n");// 輸出文檔全部 Elements links = doc.getElementsByTag("a"); for (Element ele : links) { System.out.println(ele.toString()); } }
Apache Tomcat/7.0.72
---------------------
<!doctype html>
<html lang="en">
<head>
<title>Apache Tomcat/7.0.72</title>
<link href="favicon.ico" rel="icon" type="image/x-icon">
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon">
..........
5.選擇器解析HTML并且提取input的value值:(獲取元素的屬性)
/** * <span class="bigNum">二</span>、 * <span><input class="el_modifiedTitle" value="多選題" type="text"> </span> * <span>(每到題 <input class="el_modifiedGrade" value="2" type="text"> </span> * <span> 分;共</span><span class="numTotal">4分/</span> * <span class="numQues">2題)</span> * * @param html * @return */ // 去掉大題的標簽 public static String removeBigQues(String html) { StringBuffer sb = new StringBuffer(); Document doc = Jsoup.parse(html); System.out.println(doc); System.out.println(doc.text()); sb.append(doc.select(".bigNum").get(0).text() + ". "); sb.append(doc.select(".el_modifiedTitle").get(0).attr("value")); sb.append(doc.select("span").get(2).text() + doc.select(".el_modifiedGrade").get(0).attr("value")); sb.append(doc.select("span").get(3).text()); sb.append(doc.select("span").get(4).text()); sb.append(doc.select("span").get(5).text()); System.out.println(sb.toString()); return sb.toString(); }
補充:今天發現Jsoup竟然沒有解析元素style的方法,所以只能自己手寫
先獲取到style屬性,再對style屬性進行處理,例如:
String style = "position: absolute; width: 500px; height: 552px;"; String extract = "width"; if (style.contains(extract)) { style = style.substring(style.indexOf(extract)); System.out.println(style); style = style.substring(0, style.indexOf(";")); System.out.println(style); String attr = style.substring(style.indexOf(":") + 2); System.out.println(attr.substring(0, attr.indexOf("px"))); }
補充:元素的html()與outerHtml()的區別
html()會返回包括子元素的內容以及標簽,不包括自己
outerHtml()會返回包括自己在內的元素。
在jQuery中如果返回子元素的內容也是html(),如果返回包括自己的內容需要用$("#chartdiv").prop("outerHTML");//會返回包括自己在內的內容
場景是這樣的,本來是想申請一個第三方支付接口判斷用戶支付是否成功,后來發現不需要申請接口也可以通過訂單號查詢頁面獲取支付結果,這樣就可以直接解析html來判斷支付結果了,這就引入了本文的主題,Jsoup解析html
當然jsoup不只有上面的應用場景,它還有一個應用場景,就是爬蟲!
題外話:上面場景中,使用支付接口其實才是最穩當的辦法,但是支付接口申請周期長,而且一些情況下并不是免費的,再者一些支付接口只支持一種語言,可能和本項目不是一個語言(比如項目是Java的,但是人家提供的支付接口只支持PHP),這樣增加了系統復雜度,如果業務量大且要求準確的場景下應當使用支付接口,否則可以取巧解析html,解析html有一個不好的地方就是如果html結構變化了,那么接口就得重寫,都有優缺點,看場景選擇。
官網:https://jsoup.org/
jsoup 提供了簡便的API,使用了HTML5 DOM方法和CSS選擇器用來解析HTML。其實現了WHATWG HTML5 規范,像瀏覽器一樣解析HTML。
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.2</version>
</dependency>
String html = "<html><head><title>First parse</title></head>"
+ "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);
// 簡潔版
Document doc = Jsoup.connect("http://example.com/").get();
String title = doc.title();
//完整版
doc = Jsoup.connect("http://example.com")
.data("query", "Java")
.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36")
.cookie("auth", "token")
.timeout(3000)
.post();
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
String linkHref = link.attr("href");
String linkText = link.text();
}
String html = "<p>An <a href='http://example.com/'><b>example</b></a> link.</p>";
Document doc = Jsoup.parse(html);
Element link = doc.select("a").first();
String text = doc.body().text(); // "An example link"
String linkHref = link.attr("href"); // "http://example.com/"
String linkText = link.text(); // "example""
String linkOuterH = link.outerHtml();
// "<a href="http://example.com"><b>example</b></a>"
String linkInnerH = link.html(); // "<b>example</b>"
Document doc = Jsoup.connect("http://jsoup.org").get();
Element link = doc.select("a").first();
String relHref = link.attr("href"); // == "/"
String absHref = link.attr("abs:href"); // "http://jsoup.org/"
Jsoup支持CSS選擇器,用的是 Element.select(String selector)方法
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
Elements links = doc.select("a[href]"); // a with href
Elements pngs = doc.select("img[src$=.png]");
// img with src ending .png
Element masthead = doc.select("div.masthead").first();
// div with class=masthead
Elements resultLinks = doc.select("h3.r > a"); // direct a after h3
如何快速定位頁面上元素的內容?答案是打開Chrome,按F12打開開發者工具,定位到想要的DOM節點,右鍵,copy,選擇Copy selector,即可生成CSS選擇器,類似于body > div > div.content > div.col2 > div > h3:nth-child(10)
遺憾的是Jsoup不支持Xpath選擇器,但是早就有人意識到這個問題了,所以誕生了JsoupXpath
JsoupXpath 是一款純Java開發的使用xpath解析提取html數據的解析器,針對html解析完全重新實現了W3C XPATH 1.0標準語法,xpath的Lexer和Parser基于Antlr4構建,html的DOM樹生成采用Jsoup,故命名為JsoupXpath. 為了在java里也享受xpath的強大與方便但又苦于找不到一款足夠好用的xpath解析器,故開發了JsoupXpath。JsoupXpath的實現邏輯清晰,擴展方便, 支持完備的W3C XPATH 1.0標準語法,W3C規范:http://www.w3.org/TR/1999/REC-xpath-19991116 ,JsoupXpath語法描述文件Xpath.g4
項目地址:https://github.com/zhegexiaohuozi/JsoupXpath
感興趣的可以看一下測試用例:里面包含了大量的使用場景:https://github.com/zhegexiaohuozi/JsoupXpath/blob/master/src/test/java/org/seimicrawler/xpath/JXDocumentTest.java
jsoup可以在插入、刪除、提取HTML,直接看例子代碼
//設置屬性
doc.select("div.comments a").attr("rel", "nofollow");
doc.select("div.masthead").attr("title", "jsoup").addClass("round-box");
//插入html
Element div = doc.select("div").first(); // <div></div>
div.html("<p>lorem ipsum</p>"); // <div><p>lorem ipsum</p></div>
div.prepend("<p>First</p>");
div.append("<p>Last</p>");
// now: <div><p>First</p><p>lorem ipsum</p><p>Last</p></div>
Element span = doc.select("span").first(); // <span>One</span>
span.wrap("<li><a href='http://example.com/'></a></li>");
// now: <li><a href="http://example.com"><span>One</span></a></li>
//設置文本
Element div = doc.select("div").first(); // <div></div>
div.text("five > four"); // <div>five > four</div>
div.prepend("First ");
div.append(" Last");
// now: <div>First five > four Last</div>
String unsafe =
"<p><a href='http://example.com/' onclick='stealCookies()'>Link</a></p>";
String safe = Jsoup.clean(unsafe, Whitelist.basic());
// now: <p><a href="http://example.com/" rel="nofollow">Link</a></p>
*請認真填寫需求信息,我們會在24小時內與您取得聯系。