一不小心一個月又過去了,其實最近還是小忙小忙的,廢話不多說,直接進入今天的主題吧。
Jsoup – Java HTML Parser, with best of DOM, CSS, and jquery.,看這個介紹就知道,這個就是方便咱們
Java和
android來解析
HTML的。
HTML 標簽
要去爬別人的
HTML標簽的話,首先你肯定得有一定的
HTML的基礎知識吧。比如說常用的標簽,標簽的相關屬性,這個就不多說了,有相關問題都可以在 www.w3school.com.cn 的網站解決一下。
加載網頁
最簡單的,直接加載一個網頁:
Document document = Jsoup.connect("https://www.Google.com").get();
那看到最後的
get()方法聰明滴你一定就猜到還有一個對應的
post()方法了吧。另外,
http請求的相關操作都是可以設置的,包括
header請求參數,請求超時等等。除此之外,本地的文件(IO流)等都是可以直接解析的哈。
Document document = Jsoup.connect("https://android-arsenal.com") .timeout(5000) .cookie("cookie", "cxxx") .header("xx", "xx") .userAgent("") .get();
基本標簽解析
之後咱們就得到了一個
Document的對象了。這個對象就是對整個請求網頁的封裝,相關內容都可以在裏面獲取。
來吧,加入我們有下面一段html標簽需要解析:
<div class="project-info clearfix"> <div class="header"> <div class="title"> <a href="http://blog.csdn.net/details/1/5442">RendererRecyclerViewAdapter</a> <a class="tags" href="http://blog.csdn.net/tag/199">Recycler Views</a> </div> <a class="badge free" href="http://blog.csdn.net/free">Free</a> <a class="badge new" href="http://blog.csdn.net/recent">New</a> </div> <div class="desc"> <p>A single adapter for the whole project.</p> <ul> <li>Now you do not need to implement adapters for RecyclerView.</li> <li>You can easily use several types of cells in a single list.</li> <li>Using this library will protect you from the appearance of any business logic in an adapter.</li> </ul> </div> <div class="ftr l"><i class="fa fa-calendar"></i> Mar 17, 2017</div> </div>
Jsoup裏面對於標簽的尋找使用的方法是
select()方法,這個方法不要太強大了。咱們一步一步的來。
比如我們要在茫茫標簽中找到
<div class="project-info clearfix">的話,拿這裏就是應該
findElementByClass(),那麽在
Jsoup中是怎麽定義這一塊的呢?
哈哈,很easy嘛,那就是
document.select("div.project-info clearfix")咯,當然不是這樣子的,等等
class屬性裏面這個空格是什麽意思啊?是不是一臉懵逼?這裏最終的寫法是
document.select("div.project-info.clearfix")空格需要用
.來處理。
Elements select = document.select("div.project-info.clearfix");
這裏得到是一個集合。我們接下來就需要遍歷這個集合,然後把裏面的每一個標簽都拔出來。
title 部分的解析,這裏是一個
<div>裏面嵌套了一個
<a>的標簽。這裏就涉及到了解析
<a>標簽了。這裏我們需要對應的
href,也需要對應的
text,
Jsoup提供了對應的兩個方法
attr()和
text()。
Elements elements = e.select("div.title"); if (!elements.isEmpty()) { for (Element tittle : elements) { Element first = tittle.select("a[href]").first(); if (first != null) { title = first.text(); titleUrl = first.attr("href"); system.out.println("名稱:" + title); System.out.println("具體地址:" + titleUrl); } Elements select1 = tittle.select("a.tags"); if (!select1.isEmpty()) { tag = select1.text(); tagUrl = select1.attr("href"); System.out.println("tags:" + tag); System.out.println("tagUrl:" + tagUrl); } } }
嵌套解析
到這裏,
<div>和
<a>標簽的介紹基本搞定,接下來就是
<div class="desc">的解析了。
<div class="desc"> <p>A single adapter for the whole project.</p> <ul> <li>Now you do not need to implement adapters for RecyclerView.</li> <li>You can easily use several types of cells in a single list.</li> <li>Using this library will protect you from the appearance of any business logic in an adapter.</li> </ul> </div>
這裏又多了
<ul>和
<li>了,其實道理是差不多的,但是這裏它們既沒有
class也沒有
id,那這個我們應該這麽去解析呢?
這裏還是要回到
select()方法,這裏就需要使用到指定層級的方法了。
Elements select1 = e.select("div.desc > p"); String s = select1.toString();
對於
<dt>
<dd>相關的標簽,就可以使用
+相關的連接符了。例如我想要只解析
Tag下面的對應的
Tag名稱和相關的
url,這個應該怎麽寫呢?
<dt>Tag</dt> <dd><a href="http://blog.csdn.net/tag/9">Background Processing</a></dd> <dt>License</dt> <dd><a href="http://opensource.org/licenses/Apache-2.0" rel="nofollow" target="_blank">Apache License, version 2.0</a> </dd>
代碼就是這樣的,這裏一不小心就又引出了
select()方法的嵌套高級寫法。
Elements select4 = element.select("dt:contains(Tag) + dd");
其實不用太多解釋啦,截圖裏面描述的很清楚了。最後一個是可以支持正則的匹配。
同級相鄰解析
還有一種情況就是我們需要的標簽沒有具體的
id或者
class,並且它沒有直接對應的父標簽或者某種固定的嵌套關系,例如下面這種情況:
<a id="favoriteButton" href="http://blog.csdn.net/lovejjfg/article/details/#" class="fa fa-star-o favorite tshadow" title="Add to favorites"></a> <a href="http://blog.csdn.net/details/1/5244">ImmediateLooperScheduler</a> <div id="githubInfoValue">
這裏我們只需要解析到第二個
<a>標簽,那麽需要怎麽處理呢?這裏就需要使用到
nextElementSibling()的方法了。
Element ssa = h1.select("a#favoriteButton").first(); Element element = ssa.nextElementSibling(); String title = element.text();
模糊解析
有時候我們只知道這個
<div>是以 什麽開頭或者是以什麽結尾或者又是裏面包含了某個單詞的,那麽這個時候就需要使用模糊查找了。
在
Jsoup中定義了這些情況的相關
select()寫法,其中,以什麽開頭,是使用
a[href^=http],以什麽結尾使用
a[href$=.jpg],包含什麽就是使用
a[href*=/search/]。
javascript 解析
剛剛說的都是普通標簽及其內容,如果我要獲取js相關的標簽以及內容呢?其實也不難,只是最後不是使用text()的方法,而是使用data()的方法了。
就是
Jsoup最主要的就是寫好這個
select()方法,
final Elements script = document.select("script"); String js = script.first().data();
相關實戰
Android-Arsenal 這個網站不造大家夥兒有聽說過沒?這裏給我們Android開發者提供了了一個信息交流展示平臺,實時更新一些Android相關的App,開發庫、以及Demo。然後,我看到它也有自己的客戶端,所以一時好奇也打算下載下來看看,結果,客戶端就是直接加載的網頁,關鍵是廣告滿天飛。這個就讓人不好受了(話說回來,人家不打廣告賺點兒錢做這個平臺幹嘛呢。)
所以靈機一動,為什麽我不自己搞一個
Android-Arsenal的客戶端呢?這樣方便在手機上看到最新的東西嘛。所以就做了一個客戶端,而使用的就是
Jsoup來爬去的對應的網頁。然後就把對應
ads的標簽都過濾了,所以是很清爽的啦。當然功能也只是先實現了一部分。喜歡的朋友可以點個星星或者下載使用喲!
最後來一波效果圖:
項目地址:https://github.com/lovejjfg/Android-Arsenal
—- Edit By Joe At 2017 03 18 —-
Tags:
文章來源: