java爬蟲jsoup解析HTML的工具學習
前言
使用python寫爬蟲的人,應(yīng)該都聽過beautifulsoup4這個包,用來它來解析網(wǎng)頁甚是方便。那么在java里有沒有類似的包呢?當然有啦!而且也非常好用。下面隆重介紹jsoup!
jsoup 實現(xiàn)了 WHATWG HTML5 規(guī)范,能夠與現(xiàn)代瀏覽器解析成相同的DOM。其解析器能夠盡最大可能從你提供的HTML文檔來創(chuàng)建一個干凈的解析結(jié)果,無論HTML的格式是否完整。比如它可以處理沒有關(guān)閉的標簽。
舉個栗子:
<p>Lorem <p>Ipsum parses to <p>Lorem</p> <p>Ipsum</p>
它也可以處理隱式標簽,創(chuàng)建可靠的文檔結(jié)構(gòu)(html標簽包含head 和 body,在head只出現(xiàn)恰當?shù)脑兀?/p>
下載
官網(wǎng)地址在這里
jar 包的下載地址
一個文檔的對象模型
- 文檔由多個Elements和TextNodes組成 ;
- 其繼承結(jié)構(gòu)如下:Document繼承Element繼承Node, TextNode繼承 Node.
- 一個Element包含一個子節(jié)點集合,并擁有一個父Element。他們還提供了一個唯一的子元素過濾列表。
獲取 Document 對象
jsoup 可以從包括字符串、URL 地址以及本地文件來加載 HTML 文檔,并生成 Document 對象實例。
// (1)從字符串中獲取
String html = "<html><head><title>First parse</title></head>"
+ "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc1 = Jsoup.parse(html);
// (2)從 URL 直接加載 HTML 文檔
// get方法
Document doc2 = Jsoup.connect("http://www.163.com").get();
// post方法
Document doc = Jsoup.connect("http://example.com")
.data("query", "Java")
.userAgent("Mozilla")
.cookie("auth", "token")
.timeout(3000)
.post();
// (3)從文件中加載 HTML 文檔
File input = new File("D:/test.html");
Document doc = Jsoup.parse(input,"UTF-8","http://www.163.com/");常用到的方法如下:
public static Connection connect(String url) public static Document parse(String html, String baseUri) public static Document parse(URL url, int timeoutMillis) throws IOException public static Document parse(File in, String charsetName) throws IOException public static Document parse(InputStream in, String charsetName, String baseUrl) throws IOException
parse方法能夠?qū)⑤斎氲?HTML 解析為一個新的文檔 (Document),只要解析的不是空字符串,就能返回一個結(jié)構(gòu)合理的文檔,其中包含(至少) 一個head和一個body元素。
上面的參數(shù) baseUri的作用是,如果要解析的html中存在相對路徑,那么就根據(jù)這個參數(shù)變成絕對路徑, 如果不需要可以傳入一個空字符串。
注:通過connect方法來獲得 html 源碼,有的時候會遇到亂碼的問題,這個時候該怎么辦么?方法里有一個 parse 方法,傳入?yún)?shù) InputStream、charsetName以及baseUrl,所有可以這樣解決:
String url = "http://xxxxxxx"; Document document = Jsoup.parse(new URL(url).openStream(), "GBK", url);// 以 gbk 編碼為栗。
Jsoup的強項是解析html,當然了,它能處理一些簡單情況,遇到復雜的情形還是使用 httpClient 這個包吧,你值得擁有!
解析并提取 HTML 元素
使用傳統(tǒng)的操作DOM的方式
舉個栗子
Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
Elements mx = content.getElementsByClass("help");注:doc 為 Document 對象。
還有寫常用的方法,比如
public Elements getElementsByAttributeValue(String key, String value) public Element attr(String attributeKey, String attributeValue) public Elements getAllElements() // 獲得孩子節(jié)點中所有的文本拼接 public String text() // 獲得節(jié)點的內(nèi)部html public String html()
Document 對象還有一個方法
// 獲取標題 public String title() // 獲得某節(jié)點的html,這個方法繼承自Node類,所以Element類也有該方法 public String outerHtml()
選擇器
在元素檢索方面,jsoup 的選擇器簡直無所不能。
jsoup 選擇器很多,這里僅僅舉出幾個栗子,
Elements links = doc.select("a[href]"); // 具有href屬性的a標簽
Elements pngs = doc.select("img[src$=.png]");// src屬性以.png結(jié)尾的img標簽
Element masthead = doc.select("div.masthead").first();// class屬性為masthead的div標簽中的第一個
Elements resultLinks = doc.select("h3.r > a"); // class屬性為r的h3標簽的直接子a標簽
Elements resultLinks = doc.select(img[src~=(?i)\.(png|jpe?g)])Selector選擇器概述
tagname: 通過標簽查找元素,比如:a
ns|tag: 通過標簽在命名空間查找元素,比如:可以用 fb|name 語法來查找 <fb:name> 元素
#id: 通過ID查找元素,比如:#logo
.class: 通過class名稱查找元素,比如:.masthead
[attribute]: 利用屬性查找元素,比如:[href]
[^attr]: 利用屬性名前綴來查找元素,比如:可以用[^data-] 來查找?guī)в蠬TML5 Dataset屬性的元素
[attr=value]: 利用屬性值來查找元素,比如:[width=500]
[attr^=value], [attr$=value], [attr*=value]: 利用匹配屬性值開頭、結(jié)尾或包含屬性值來查找元素,比如:[href*=/path/]
[attr~=regex]: 利用屬性值匹配正則表達式來查找元素,比如: img[src~=(?i)\.(png|jpe?g)]
*: 這個符號將匹配所有元素
Selector選擇器組合使用
el#id: 元素+ID,比如: div#logo
el.class: 元素+class,比如: div.masthead
el[attr]: 元素+class,比如: a[href]
任意組合,比如:a[href].highlight
ancestor child: 查找某個元素下子元素,比如:可以用.body p 查找在"body"元素下的所有 p元素
parent > child: 查找某個父元素下的直接子元素,比如:可以用div.content > p 查找 p 元素,也可以用body > * 查找body標簽下所有直接子元素
siblingA + siblingB: 查找在A元素之前第一個同級元素B,比如:div.head + div
siblingA ~ siblingX: 查找A元素之前的同級X元素,比如:h1 ~ p
el, el, el:多個選擇器組合,查找匹配任一選擇器的唯一元素,例如:div.masthead, div.logo
偽選擇器selectors
:lt(n): 查找哪些元素的同級索引值(它的位置在DOM樹中是相對于它的父節(jié)點)小于n,比如:td:lt(3) 表示小于三列的元素
:gt(n):查找哪些元素的同級索引值大于n,比如: div p:gt(2)表示哪些div中有包含2個以上的p元素
:eq(n): 查找哪些元素的同級索引值與n相等,比如:form input:eq(1)表示包含一個input標簽的Form元素
:has(seletor): 查找匹配選擇器包含元素的元素,比如:div:has(p)表示哪些div包含了p元素
:not(selector): 查找與選擇器不匹配的元素,比如: div:not(.logo) 表示不包含 class=logo 元素的所有 div 列表
:contains(text): 查找包含給定文本的元素,搜索不區(qū)分大不寫,比如: p:contains(jsoup)
:containsOwn(text): 查找直接包含給定文本的元素
:matches(regex): 查找哪些元素的文本匹配指定的正則表達式,比如:div:matches((?i)login)
:matchesOwn(regex): 查找自身包含文本匹配指定正則表達式的元素
注: 上述偽選擇器索引是從0開始的,也就是說第一個元素索引值為0,第二個元素index為1等。
對于 Elements 的來歷,看這里
public class Elements extends ArrayList<Element>
另外,可以查看Selector API參考來了解更詳細的內(nèi)容,可以看出,jsoup 使用跟 jQuery 一模一樣的選擇器對元素進行檢索,以上的檢索方法如果換成是其他的 HTML 解釋器,至少都需要很多行代碼,而 jsoup 只需要一行代碼即可完成。
修改獲取數(shù)據(jù)
// 為所有鏈接增加 rel=nofollow 屬性
doc.select("div.comments a").attr("rel", "nofollow");
// 為所有鏈接增加 class=mylinkclass 屬性
doc.select("div.comments a").addClass("mylinkclass");
// 刪除所有圖片的 onclick 屬性
doc.select("img").removeAttr("onclick");
// 清空所有文本輸入框中的文本
doc.select("input[type=text]").val("");
// 獲得rel屬性的值
doc.select("div.comments a").attr("rel");參考
以上就是java爬蟲工具jsoup解析HTML的工具學習的詳細內(nèi)容,更多關(guān)于java爬蟲工具jsoup的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring核心容器之ApplicationContext上下文啟動準備詳解
這篇文章主要介紹了Spring核心容器之ApplicationContext上下文啟動準備詳解,ApplicationContext 繼承自 BeanFactory ,其不僅包含 BeanFactory 所有功能,還擴展了容器功能,需要的朋友可以參考下2023-11-11
SpringMVC?bean實現(xiàn)加載控制方法詳解
SpringMVC是一種基于Java,實現(xiàn)了Web?MVC設(shè)計模式,請求驅(qū)動類型的輕量級Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進行職責解耦?;谡埱篁?qū)動指的就是使用請求-響應(yīng)模型,框架的目的就是幫助我們簡化開發(fā),SpringMVC也是要簡化我們?nèi)粘eb開發(fā)2022-08-08
關(guān)于Springboot的擴展點DisposableBean的原理解析
這篇文章主要介紹了關(guān)于Springboot的擴展點DisposableBean的原理解析,DisposableBean是一個接口,為Spring bean提供了一種釋放資源的方式 ,只有一個擴展方法destroy(),需要的朋友可以參考下2023-05-05
JAVA開發(fā)中的一些規(guī)范講解(阿里巴巴Java開發(fā)規(guī)范手冊)
這篇文章主要介紹了JAVA開發(fā)中的一些規(guī)范講解(阿里巴巴Java開發(fā)規(guī)范手冊),需要的朋友可以參考下2018-04-04
SpringBoot綁定配置文件中變量的四種方式總結(jié)
當在Spring Boot中需要綁定配置文件中的變量時,可以使用以下注解:@PropertySourc,@Value,@Environment,@ConfigurationProperties,具體實現(xiàn)代碼示例文中講解的非常詳細,需要的朋友可以參考下2023-11-11
SpringBoot默認使用HikariDataSource數(shù)據(jù)源方式
這篇文章主要介紹了SpringBoot默認使用HikariDataSource數(shù)據(jù)源方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
Mybatis中的resultType和resultMap查詢操作實例詳解
resultType是直接表示返回類型的,而resultMap則是對外部ResultMap的引用,resultMap解決復雜查詢是的映射問題。這篇文章主要介紹了Mybatis中的resultType和resultMap查詢操作實例詳解,需要的朋友可以參考下2016-09-09

