Java爬蟲系列三:使用Jsoup解析HTML

在上一篇隨筆《Java爬蟲系列二:使用HttpClient抓取頁面HTML》中介紹了怎么使用HttpClient進行爬蟲的第一步--抓取頁面html俘侠,今天接著來看下爬蟲的第二步--解析抓取到的html彬向。

有請第二步的主角:Jsoup粉墨登場娃胆。

一、Jsoup自我介紹

大家好凿蒜,我是Jsoup废封。

我是一款Java 的HTML解析器丧蘸,可直接解析某個URL地址、HTML文本內(nèi)容刽漂。它提供了一套非常省力的API弟孟,可通過DOM拂募,CSS以及類似于jQuery的操作方法來取出和操作數(shù)據(jù)窟她,用Java寫爬蟲的同行們十之八九用過我震糖。為什么呢试伙?因為我在這個方面功能強大于样、使用方便穿剖。不信的話卦溢,可以繼續(xù)往下看糊余,代碼是不會騙人的。

二单寂、Jsoup解析html

上一篇中贬芥,HttpClient大哥已經(jīng)抓取到了博客園首頁的html,但是一堆的代碼宣决,不是程序員的人們怎么能看懂呢蘸劈?這個就需要html解析專家出場了。

下面通過案例展示如何使用Jsoup進行解析尊沸,案例中將獲取博客園首頁的標(biāo)題和第一頁的博客文章列表

請看代碼(在上一篇代碼的基礎(chǔ)上進行操作威沫,如果還不知道如何使用httpclient的朋友請?zhí)D(zhuǎn)頁面進行閱讀):

引入依賴

<dependency>

? ? <groupId>org.jsoup</groupId>

? ? <artifactId>jsoup</artifactId>

? ? <version>1.12.1</version>

</dependency>

實現(xiàn)代碼。實現(xiàn)代碼之前首先要分析下html結(jié)構(gòu)棒掠。標(biāo)題是<title>不用說了,那文章列表呢屁商?按下瀏覽器的F12烟很,查看頁面元素源碼,你會發(fā)現(xiàn)列表是一個大的div蜡镶,id="post_list",每篇文章是小的div,class="post_item"

接下來就可以開始代碼了雾袱,Jsoup核心代碼如下:

/**

? ? ? ? ? ? ? ? * 下面是Jsoup展現(xiàn)自我的平臺

? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? //6.Jsoup解析html

? ? ? ? ? ? ? ? Document document = Jsoup.parse(html);

? ? ? ? ? ? ? ? //像js一樣,通過標(biāo)簽獲取title

? ? ? ? ? ? ? ? System.out.println(document.getElementsByTag("title").first());

? ? ? ? ? ? ? ? //像js一樣帽哑,通過id 獲取文章列表元素對象

? ? ? ? ? ? ? ? Element postList = document.getElementById("post_list");

? ? ? ? ? ? ? ? //像js一樣谜酒,通過class 獲取列表下的所有博客

? ? ? ? ? ? ? ? Elements postItems = postList.getElementsByClass("post_item");

? ? ? ? ? ? ? ? //循環(huán)處理每篇博客

? ? ? ? ? ? ? ? for (Element postItem : postItems) {

? ? ? ? ? ? ? ? ? ? //像jquery選擇器一樣,獲取文章標(biāo)題元素

? ? ? ? ? ? ? ? ? ? Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");

? ? ? ? ? ? ? ? ? ? System.out.println("文章標(biāo)題:" + titleEle.text());;

? ? ? ? ? ? ? ? ? ? System.out.println("文章地址:" + titleEle.attr("href"));

? ? ? ? ? ? ? ? ? ? //像jquery選擇器一樣僻族,獲取文章作者元素

? ? ? ? ? ? ? ? ? ? Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");

? ? ? ? ? ? ? ? ? ? System.out.println("文章作者:" + footEle.text());;

? ? ? ? ? ? ? ? ? ? System.out.println("作者主頁:" + footEle.attr("href"));

? ? ? ? ? ? ? ? ? ? System.out.println("*********************************");

? ? ? ? ? ? ? ? }

根據(jù)以上代碼你會發(fā)現(xiàn)述么,我通過Jsoup.parse(String html)方法對httpclient獲取到的html內(nèi)容進行解析獲取到Document度秘,然后document可以有兩種方式獲取其子元素:像js一樣 可以通過getElementXXXX的方式 和 像jquery 選擇器一樣通過select()方法。 無論哪種方法都可以唆貌,我個人推薦用select方法處理锨咙。對于元素中的屬性酪刀,比如超鏈接地址钮孵,可以使用element.attr(String)方法獲取巴席, 對于元素的文本內(nèi)容通過element.text()方法獲取情妖。

執(zhí)行代碼,查看結(jié)果(不得不感慨博客園的園友們真是太厲害了毡证,從上面分析首頁html結(jié)構(gòu)到Jsoup分析的代碼執(zhí)行完,這段時間首頁多了那么多文章)

三丐箩、Jsoup的其他用法

我恤煞,Jsoup,除了可以在httpclient大哥的工作成果上發(fā)揮作用概漱,我還能自己獨立干活喜喂,自己抓取頁面,然后自己分析腻异。分析的本領(lǐng)已經(jīng)在上面展示過了悔常,下面來展示自己抓取頁面机打,其實很簡單姐帚,所不同的是我直接獲取到的是document,不用再通過Jsoup.parse()方法進行解析了唯蝶。

除了能直接訪問網(wǎng)上的資源粘我,我還能解析本地資源:

代碼:

public static void main(String[] args) {

? ? ? ? try {

? ? ? ? ? ? Document document = Jsoup.parse(new File("d://1.html"), "utf-8");

? ? ? ? ? ? System.out.println(document);

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? }

四、Jsoup另一個值得一提的功能

你肯定有過這種經(jīng)歷痹换,在你的頁面文本框中征字,如果輸入html元素的話娇豫,保存后再查看很大概率會導(dǎo)致頁面排版亂七八糟,如果能對這些內(nèi)容進行過濾的話冯痢,就完美了氮昧。

剛好我Jsoup就能做到浦楣。

public static void main(String[] args) {

? ? ? ? String unsafe = "<p><a href='網(wǎng)址' onclick='stealCookies()'>博客園</a></p>";

? ? ? ? System.out.println("unsafe: " + unsafe);

? ? ? ? String safe = Jsoup.clean(unsafe, Whitelist.basic());

? ? ? ? System.out.println("safe: " + safe);

? ? }

通過Jsoup.clean方法袖肥,用一個白名單進行過濾。執(zhí)行結(jié)果:

unsafe: <p><a href='網(wǎng)址' onclick='stealCookies()'>博客園</a></p>

safe: <p><a rel="nofollow">博客園</a></p>

五振劳、結(jié)束語

不僅可以解析HttpClient抓取到的html元素,自己也能抓取頁面dom历恐,還能load并解析本地保存的html文件。

此外灵份,還能通過一個白名單對字符串進行過濾弦聂,篩掉一些不安全的字符氛什。

最最重要的,上面所有功能的API的調(diào)用都比較簡單捺檬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贸铜,一起剝皮案震驚了整個濱河市堡纬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒿秦,老刑警劉巖烤镐,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異棍鳖,居然都是意外死亡炮叶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門渡处,熙熙樓的掌柜王于貴愁眉苦臉地迎上來镜悉,“玉大人,你說我怎么就攤上這事医瘫÷乱蓿” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵登下,是天一觀的道長茫孔。 經(jīng)常有香客問我,道長被芳,這世上最難降的妖魔是什么缰贝? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮畔濒,結(jié)果婚禮上剩晴,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好赞弥,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布毅整。 她就那樣靜靜地躺著,像睡著了一般绽左。 火紅的嫁衣襯著肌膚如雪悼嫉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天拼窥,我揣著相機與錄音戏蔑,去河邊找鬼。 笑死鲁纠,一個胖子當(dāng)著我的面吹牛总棵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播改含,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼情龄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捍壤?” 一聲冷哼從身側(cè)響起骤视,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹃觉,沒想到半個月后尚胞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡帜慢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了唯卖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粱玲。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拜轨,靈堂內(nèi)的尸體忽然破棺而出抽减,到底是詐尸還是另有隱情,我是刑警寧澤橄碾,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布卵沉,位于F島的核電站,受9級特大地震影響法牲,放射性物質(zhì)發(fā)生泄漏史汗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一拒垃、第九天 我趴在偏房一處隱蔽的房頂上張望停撞。 院中可真熱鬧,春花似錦、人聲如沸戈毒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽埋市。三九已至冠桃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間道宅,已是汗流浹背食听。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留培己,地道東北人碳蛋。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像省咨,于是被迫代替她去往敵國和親肃弟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容