天天看點

Java爬蟲之學習篇 Jsoup爬取頁面

不知不覺在這個爬蟲行業工作半年多了。在網上看到的java文章大多都是比較簡單的一個例子。

沒有太多系統的總結的專欄,既然沒有的話,我就自己寫一個吧。不足之處希望大家,多多指點.

此篇主要内容: jsoup的使用, 對不同資料類型抓取. 對資料的抽取:

開始前,先介紹下Jsoup。

Jsoup是java的一個開源,可以來模拟浏覽器來擷取網頁資料的架構。也就是可以實作爬蟲的功能,知道這個就行了。有興趣深入的小夥伴。可以觀看下面官方文檔 。

jsoup官方的文檔:https://www.open-open.com/jsoup/ 這是一篇中文官方的文檔。

下面開始介紹Jsoup: 按功能分類的話:Josup可以分為兩類:抓取資料,資料抽取。下面就這兩個功能開始詳細說明。

抓取資料:從頁面中将資料爬下來。

抓取資料的一些前期準備工作:

一、fiddler抓包工具

官網下載下傳位址:http://www.telerik.com/fiddler

這種需要抓包工具,抓取參數。向大家推薦fiddler.上網有許多大佬,寫了很詳細的介紹,我就不獻醜了。就推薦一篇

fiddler使用介紹:https://www.cnblogs.com/ink-marks/p/6363275.html

二、jar包 的下載下傳(之後再補充吧)

下面進入主題,開始爬資料了。

首先:爬資料之前,我們應該知道,想要爬取的網站是以什麼向伺服器發出的請求,傳回的資料又是什麼格式。知道這些,後面就可以想套公示一樣去解析該網站。

浏覽器向伺服器端請求的方式,大多分為post與get。而傳回的資料類型,一般為html與json兩種格式。(目前我隻碰到這些)

是以組合一下,網站大緻可以為4種爬取資料的類型,本文針對這4種資料類型分别說明

get請求,傳回html格式的資料.的情況

Document doc = Jsoup.connect(url)   //url 是浏覽器位址欄的連接配接,直接放入就可以了
			 .timeout(1000*10)      //通路時長的設定
			 .get();		       //get請求
           

post請求,傳回html格式的資料.的情況

post請求則需要抓包工具,來幫助我們,來獲得傳遞的參數了

get請求,傳回json格式的資料.的情況

post請求,傳回json格式的資料.的情況

之後補充,再将4個demo 的例子傳上來.

資料抽取 基本上從上述官方文檔中擷取的。

一、使用dom方法來周遊一個Document對象

Java爬蟲之學習篇 Jsoup爬取頁面

官方的文檔:https://www.open-open.com/jsoup/dom-navigation.htm 類似js的一些使用

二、選擇器

jsoup elements對象支援類似于CSS (或jquery)的選擇器文法,來實作非常強大和靈活的查找功能。.

這個select 方法在Document, Element,或Elements對象中都可以使用。且是上下文相關的,是以可實作指定元素的過濾,或者鍊式選擇通路。

Select方法将傳回一個Elements集合,并提供一組方法來抽取和處理結果。

Selector選擇器概述

tagname: 通過标簽查找元素,比如:a
ns|tag: 通過标簽在命名空間查找元素,比如:可以用 fb|name 文法來查找 <fb:name> 元素
#id: 通過ID查找元素,比如:#logo
.class: 通過class名稱查找元素,比如:.masthead
[attribute]: 利用屬性查找元素,比如:[href]
[^attr]: 利用屬性名字首來查找元素,比如:可以用[^data-] 來查找帶有HTML5 Dataset屬性的元素
[attr=value]: 利用屬性值來查找元素,比如:[width=500]
[attr^=value], [attr$=value], [attr*=value]: 利用比對屬性值開頭、結尾或包含屬性值來查找元素,比如:[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樹中是相對于它的父節點)小于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): 查找包含給定文本的元素,搜尋不區分大不寫,比如: p:contains(jsoup)
:containsOwn(text): 查找直接包含給定文本的元素
:matches(regex): 查找哪些元素的文本比對指定的正規表達式,比如:div:matches((?i)login)
:matchesOwn(regex): 查找自身包含文本比對指定正規表達式的元素
           

三、元素抽取屬性,文本和HTML

方法

要取得一個屬性的值,可以使用Node.attr(String key) 方法

對于一個元素中的文本,可以使用Element.text()方法

對于要取得元素或屬性中的HTML内容,可以使用Element.html(), 或 Node.outerHtml()方法

示例:

String html = "<p>An <a href='http://example.com/'><b>example</b></a> link.</p>";
Document doc = Jsoup.parse(html);//解析HTML字元串傳回一個Document實作
 Element link = doc.select("a").first();//查找第一個a元素

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" target="_blank" rel="external nofollow" ><b>example</b></a>"
String linkInnerH = link.html(); // "<b>example</b>"//取得連結内的html内容
           

說明

上述方法是元素資料通路的核心辦法。此外還其它一些方法可以使用:

Element.id()
Element.tagName()
Element.className() and Element.hasClass(String className)