1. 程式人生 > >因為jsoup,再見了我的htmlparser

因為jsoup,再見了我的htmlparser

jsoup,一款Java 的HTML解析器,可直接解析某個URL地址、HTML文字內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似於jQuery的操作方法來取出和操作資料。
前幾天還在使用htmlparser來爬蟲的我,現在我要因為jsoup跟htmlparser道別了,畢竟htmlparser的最新版是在十年前出的,而現在有更優秀的解析器的出現了。


為什麼說jsoup這麼好?



1.獲取工具包的方式

從獲取它的jar包的方式,就已經讓我對它產生了好感,人的第一感覺十分重要,篩選工具時同樣會有第一感覺。
如何獲取jsoup的jar包呢?

把你的工程設定成maven的屬性的專案


點開連結獲取指定的程式碼,然後按下面指

示操作就可以匯入jar包了。



完全不需要下載檔案,而且匯入幾個jar包都是這麼方便,再也不用擔心下載不了檔案或者找不到下載檔案了。



2.熟悉和簡便的語言風格

它的語言風格與javaScript和jQuery很相似,如果你懂得html語言,那麼給你的感覺就是在寫html的程式碼或者就是在寫JavaScript的程式碼。

只需要簡單的幾行程式碼就可以從許多資訊的網頁中精準獲取你想要的資訊,無論是獲取連線還是過濾資訊的過程,都只是幾行程式碼就可以解決的事情。

3.強大的過濾器(也是最重要的原因)
來看看幾個強大的方法:
Elements物件下的方法

(1).getElementById(String id)

根據id屬性的屬性值來獲取元素


(2).getElementByAttribute(String key)
根據屬性名key來獲取元素 
例:getElementByAttribute("value")
獲取有value屬性的所有元素


(3).getElementByAttributeValue(String key,String value)
根據屬性名key=value這個屬性值來獲取元素
例:getElementByAttributeValue("name","abc")
獲取屬性name=abc的元素


(4).getElementByAttributeValueContaining(String key,String match)

根據屬性名key的屬性值 包含 match屬性值來獲取元素
例:getElementByAttributeValueContaining(name,a)
獲取屬性name的值 包含 a的元素


(5).getElementByAttributeValueStarting(String key,String valuePrefix)

根據屬性名key的屬性 以valuePrefix開頭的屬性值來獲取元素
例:getElementByAttributeValueStarting(class,red)

獲取屬性class的值以red開頭的元素

這裡都是過濾元素的方法(詳情去檢視API文件 點選開啟連結):


4.介紹了這麼多,下面來演示jsoup的強大之處並且與htmlparser進行對比

來個簡單的任務,獲取這個網頁的圖片的下載地址:


分析網頁的原始碼:


使用htmlparser程式碼:

public static void getDownloadUrl(String introUrl){
		String downloadUrl="";
		try {
			Document doc=Jsoup.connect(introUrl).get();
			Element element=doc.getElementById("J_worksImg");
			downloadUrl=element.attr("src");
			System.out.println(downloadUrl);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		getDownloadUrl("http://www.nipic.com/show/15949460.html");
	}


使用jsoup程式碼:

public static void getDownloadUrl(String introUrl){
		String downloadUrl="";
		try {
			Document doc=Jsoup.connect(introUrl).get();
			Element element=doc.getElementById("J_worksImg");
			downloadUrl=element.attr("src");
			System.out.println(downloadUrl);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		getDownloadUrl("http://www.nipic.com/show/15949460.html");
	}


顯然,htmlparser的程式碼比較複雜,而且行數也比較多,使用的方法也難記,方法名也很難讓使用者理解方法的用途。

jsoup的程式碼看起來很簡練,方法名也容易理解,即便第一次使用也容易掌握。

5.這個還不能體現出jsoup的強大之處,我們把抓取資訊的難度調大一點。

場景:

上次我們已經學會獲取一個電影網頁的所有介紹地址,然後再獲取每個電影的下載地址,這次我們把電影網站的所有分頁都獲取過來,迴圈一下就可以獲取所有的電影下載地址。


下一步我們就來分析如何獲取所有分頁的地址:

(檢視並分析網頁的原始碼)


分析1:


分析2:


jsoup程式碼示例:

public static void getAllPage(String url) {
		try {
			Document doc=Jsoup.connect(url).get();
			Elements elements=doc.getElementsByAttributeValueContaining("value", "list");
			for (int i = 0; i < elements.size(); i++) {
				Element e=elements.get(i);
				System.out.println("http://www.ygdy8.net/html/gndy/dyzz/"+e.attr("value"));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		getAllPage("http://www.ygdy8.net/html/gndy/dyzz/index.html");
	}


htmlparser程式碼示例:

public static void getAllPage(String url) {
		try {
			Parser parser = new Parser(url);
			NodeList list=parser.extractAllNodesThatMatch(new TagNameFilter("option"));
			for(int i=0;i<list.size();i++){
				Tag tag=(Tag) list.elementAt(i);
				String tmp=tag.getAttribute("value");
				if(tmp.contains("list")){
					System.out.println("http://www.ygdy8.net/html/gndy/dyzz/"+tmp);
				}
			}
		} catch (ParserException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		getAllPage("http://www.ygdy8.net/html/gndy/dyzz/index.html");
	}


關於jsoup更多的使用可以到一下地址檢視: