著Web的發展,人們越來越需要從互聯網上獲取數據并進行分析。為此,Java提供了一個功能強大的庫——Jsoup,它可以幫助我們輕松地從Web頁面中提取信息。在這篇文章中,我們將探討如何使用Java和Jsoup來實現一個簡單的網絡爬蟲。
Jsoup是一款基于Java的HTML解析器,可以將HTML文檔轉換為可操作的Java對象。Jsoup提供了一些簡單而方便的API來解析HTML,例如選擇器API、DOM操作API、屬性處理API等。這使得我們可以輕松地從Web頁面中提取所需的數據。由于Jsoup的高度靈活性和易用性,它被廣泛應用于Web抓取和數據挖掘領域。
在編寫我們的網絡爬蟲之前,我們需要做一些準備工作。首先,我們需要安裝Java和Jsoup,并設置Java環境變量。然后,我們需要確定我們要從哪個網站獲取數據,并了解該網站的結構。在這個例子中,我們將使用豆瓣電影作為我們的目標網站,并從該網站獲取電影的基本信息。
在Java中使用Jsoup非常簡單。我們只需要在Java項目中導入Jsoup庫,并使用以下代碼創建一個Document對象
Document doc=Jsoup.connect("https://movie.douban.com/top250").get();
這個代碼將會從豆瓣電影的Top250頁面中獲取數據,并創建一個Document對象來存儲這些數據。我們可以使用Document對象的方法來解析HTML文檔,并提取我們需要的信息。例如,我們可以使用以下代碼來獲取頁面的標題:
String title=doc.title();
在這個例子中,我們將獲取頁面的標題作為一個字符串。我們可以在控制臺上輸出這個字符串,以驗證我們的代碼是否有效:
System.out.println("頁面標題是:" + title);
如果一切正常,我們應該能夠在控制臺上看到頁面的標題。
現在我們已經成功地從豆瓣電影的Top250頁面中獲取了HTML文檔,并將其存儲在了一個Document對象中。接下來,我們需要從這個HTML文檔中提取我們所需的信息。在這個例子中,我們將提取電影的基本信息,例如電影名稱、導演、演員、評分和評論數等。
我們可以使用Jsoup提供的選擇器API來輕松地選擇HTML文檔中的元素。例如,如果我們想選擇頁面上所有的電影條目,我們可以使用以下代碼:
Elements movieElements=doc.select("div.item");
這個代碼將會從HTML文檔中選擇所有class為item的div元素,并將它們存儲在一個Elements對象中。接下來,我們可以遍歷這些元素,并提取我們所需的信息。例如,我們可以使用以下代碼獲取每個電影的名稱和評分:
for (Element movie : movieElements) {
String title=movie.select("div.hd a span").text();
String rating=movie.select("span.rating_num").text();
System.out.println("電影名稱:" + title + ",評分:" + rating);
}
在這個例子中,我們使用選擇器API來選擇每個電影條目中的電影名稱和評分元素。然后,我們使用text()方法來獲取這些元素的文本內容,并將它們打印到控制臺上。
我們還可以使用選擇器API來選擇其他元素,例如導演和演員。例如,我們可以使用以下代碼獲取每個電影的導演和演員:
for (Element movie : movieElements) {
String directors=movie.select("div.bd p").first().ownText();
String actors=movie.select("div.bd p").get(1).ownText();
System.out.println("導演:" + directors + ",演員:" + actors);
}
在這個例子中,我們使用選擇器API來選擇每個電影條目中的導演和演員元素。然后,我們使用ownText()方法來獲取這些元素的文本內容,并將它們打印到控制臺上。
到目前為止,我們已經成功地從豆瓣電影的Top250頁面中提取了電影的基本信息。然而,Top250頁面只包含前250部電影的信息,如果我們想獲取更多的電影信息,我們需要使用分頁來獲取。
在豆瓣電影中,每個頁面最多顯示25部電影。因此,如果我們想獲取前1000部電影的信息,我們需要遍歷40個頁面。為了實現這個功能,我們需要使用循環來遍歷每個頁面,并提取每個頁面中的電影信息。例如,我們可以使用以下代碼獲取前1000部電影的信息:
for (int i=0; i < 40; i++) {
String url="https://movie.douban.com/top250?start=" + i * 25;
Document doc=Jsoup.connect(url).get();
Elements movieElements=doc.select("div.item");
for (Element movie : movieElements) {
String title=movie.select("div.hd a span").text();
String rating=movie.select("span.rating_num").text();
String directors=movie.select("div.bd p").first().ownText();
String actors=movie.select("div.bd p").get(1).ownText();
System.out.println("電影名稱:" + title + ",評分:" + rating + ",導演:" + directors + ",演員:" + actors);
}
}
在這個例子中,我們使用循環來遍歷前40個頁面。
問題1:使用Jsoup抓取數據時,如果網站是https開頭,可能存在證書SSL證書安全的問題,無法直接爬蟲。請求會報錯:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
解決方案有很多,這里推薦一種封裝一個工具類,在爬蟲之前調用一下這個方法即可。
import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JsoupUtil {
public static void trustEveryone() {
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context=SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
}
以下是一個完整的示例:
import com.ruoyi.aqosc.util.JsoupUtil;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class PaChongDemo {
public static void main(String[] args) throws IOException {
JsoupUtil.trustEveryone();
//要爬取的網站
String url="https://jxj.anqing.gov.cn/xxfb/tzgg/index.html";
//獲得一個和網站的鏈接,注意是Jsoup的connect
Connection connect=Jsoup.connect(url);
//獲得該網站的Document對象
Document document=connect.get();
//我們可以通過對Document對象的select方法獲得具體的文本內容
Elements rootselect=document.select(".navjz ul li");
for(Element ele : rootselect){
Elements dateElements=ele.select(".right.date");
//發布時間
String date=dateElements.text();
System.out.println("發布時間:"+date);
//然后獲得a標簽里面具體的內容
Elements titleElements=ele.select("a");
//文章名稱
String title=titleElements.attr("title");
System.out.println("文章名稱:"+title);
//文章鏈接
String sourceUrl=titleElements.attr("href");
System.out.println("文章鏈接:"+sourceUrl);
}
}
}
運行之后控制臺打印結果:
有時候需要進入詳情頁面獲取更多詳細信息,比如作者,正文,附件之類的,跟上面類似,前面已經拿到了文章鏈接,拿文章鏈接跟上面一樣再去執行一次 Connection connect=Jsoup.connect(文章鏈接);獲取頁面元素即可。
問題2:如果正文內的圖片、附件之類的使用的是相對路徑,因為抓取之后到新的服務器,前綴變了,新的服務器對應的路徑并沒有相應的文件,在前端顯示的時候就會提示找不到,如何處理呢?處理方法也比較簡單,就是進行地址轉化,使用絕對地址。
Elements links=element.select("a");
for(Element link: links){
link.attr("href",link.attr("abs:href"));
}
Elements imgs=element.select("img");
for(Element img: imgs){
img.attr("src",img.attr("abs:src"));
}
查找"a"和"img",將其中的href元素值修改為絕對路徑。link.attr("abs:href")將會得到對應鏈接的絕對路徑,其中屬性為abs:href。同理,img.attr("abs:src")可以得到圖片絕對路徑abs:src。
以下是一個詳細的demo:
你太美。
雖然第一個html代碼寫的非常隨意,就四個字:雞你太美。但是用瀏覽器打開之后確實是能看到是以網頁的形式所展現的。這個現象就有點奇怪了,為什么?講道理,只要是一種語言,必定有自己的語法格式,得按它的套路去寫才能認為代碼寫的是對的,然后才能去正常的運行。
但是這里就四個字:雞你太美,它就能把這個東西給顯示出來,這是為什么?其實很簡單。
·可以看一下,按一下F12,把瀏覽器的開發者工具給打開。
·然后選中elements標簽頁,如果是中文版,這里就應該是元素。
·這里有4行文本,這4行文本里面有沒有一個比較熟悉的東西?雞你太美這四個字是不是HTML代碼里面寫的東西?如果把這個東西改了,雞你太美baby。
·然后就不再打開HTML文件了,直接按刷新。這里變成了雞你太美baby,這里是不是也變成了雞你太美baby。
·再比如加點東西,保存刷新,有沒有發現什么規律?這里寫什么,這一段就是什么,但其他地方是沒變的。
所以有理由相信這份代碼的完全體應該是什么?應該就是這個。所以先來把它復刻一下,尖括號。要注意,尖括號得是英文輸入法下的尖括號。html,有個had,后面又有一個head,只不過head前面加了一個斜杠。至于這些東西到底是什么意思,等一下再說。
先把代碼搞完,雞左邊有個body,后面有個body,下面又有一個斜杠。html好保存,然后刷新,效果和之前的閹割版是一樣的。
然后來看一下這些尖括號到底是什么意思,其實還是挺簡單的。首先在html里面,像這種用尖括號括起來的東西稱之為元素。在國內有的人喜歡把它稱為標簽,其實都是一個意思,就是元素的意思。所以在這里有幾種元素,很明顯是三種,一種是html,一種是head,還有一種是body。
這個時候有的小白可能會問了,為什么有的前面是加了個斜杠的?其實是這樣子的,在html里面有些元素是有包裹區間的,就比如body元素,body元素里面的數據或者叫內容是從哪到哪?很明顯這個是開頭,這個是結尾,然后掐頭去尾,內容就在這,懂了吧?開頭結尾。
所以head元素的數據在哪?就在這,什么都沒有。head元素的數據在哪?很明顯就是這個。知道元素的概念之后,接下來再看一下這幾種元素都是什么意思。
·首先html元素是告訴瀏覽器,接下來是html代碼。
·然后head還有body是什么意思?其實可以把HTML代碼想象成是一個人,一個人有自己的頭,還有身體,而且人家的腦袋里面此時此刻在想什么是看不出來的。所以head元素里面的內容一般都是去寫一些對于頁面的一些設置,或者在這個區域里面所看不到的一些東西。
就比如里面可以再加個元素,比如說叫title,title我相信大家應該都知道,就是標題的意思,這個也是一樣的,起止。然后中間這里寫什么?選項卡的這里名字就是什么?就比如坤坤牛逼,保存,然后刷新,是不是變成了坤坤牛逼?當然,想把這個東西放到別的地方也行,比如說放到body里面,然后保存,一刷新,你看也是坤坤牛逼,對吧?但是一般來說按照規范,一般是放到這種head元素里面去,這是head元素。
·然后接下來是body,body就是人的身體,人家長得什么樣子,身材好不好,到底前凸不凸,后翹不翹,一眼就能看得出來,多看一眼都會爆炸的那種。所以在body元素里面,一般都是寫一些在這個區域里面能看到的東西,就比如說一些文字或者說一些圖片等等,所以這個才是html代碼最基本的結構。
·然后回過頭來再看一下最初的問題,什么?就是一開始代碼不是這個樣子的嗎?沒有,那些head、html、body卻依然能在瀏覽器上正確的顯示出來。其實很簡單,就是因為雖然就寫了這個東西,但是瀏覽器會讀取代碼文件里面所寫的內容,寫了什么就能讀到什么。
如果代碼不夠規范,瀏覽器就會自動的幫你把這些元素給補齊,補齊完之后才是真正的HTML代碼。有了正確的代碼之后,瀏覽器才會根據這份代碼來進行渲染,也就是現在所看到的樣子。
所以代碼千萬條,規范第一條,因為永遠都不會想知道瀏覽器到底會對不規范的代碼進行什么樣的修改,把它改成什么樣子。所以html代碼的最基本的格式就是html、head、body。修改后的結果:雞你太美。
HTML 代表超文本標記語言。它給出了網站或網頁的基本結構。它定義了您的網站在結構方面的外觀,即網站包含標題、輸入、表單、表格、按鈕等等。
HTML 代碼
<!DOCTYPE html>
<html>
<head>
<title>Hello world</title>
</head>
<body>
<h1>Hello world</h1>
</body>
</html>
您可以在此處查看 Hello world 網站的實時版本,其代碼寫在上面。
我們將詳細討論每一行代碼,以便您能夠了解每一行的想法。
這一行基本上告訴網絡瀏覽器我們正在使用哪個HTML版本。在本例中我們是HTML5。
這是包含我們網頁的所有代碼的HTML元素。換句話說,這包含了網頁所需的所有結構和設置,即外部 CSS、JS、CDN 等。您可能會注意到所有內容都位于<html>和之間</html>。這是因為這樣所有的內容都會在這些元素之間。<html>通常指的是開始標簽,</html>通常指的是結束標簽。
該元素包含了網頁的所有要求。例如,如果您想添加一些外部 CSS 文件、外部 JS 文件或一些外部 CDN(這是網站的要求),那么此元素就會派上用場。如果您不了解 CSS,它用于樣式目的,JS 用于功能目的,CDN 代表內容交付網絡。
該元素包含顯示在Web 瀏覽器選項卡中的標題。如果您訪問 Hello world 網站,您會注意到網絡瀏覽器的選項卡中有標題。這是這些標簽的主要工作。Hello world<title>...</title>
該元素包含用戶可見的結構。您可以想象到的上述元素可以用于我們網頁的設置。主要內容進入正文部分。
h1是用于標題的標題元素。如果您訪問 hello world 網站,我們可以看到的 hello world 就是標題。h1不僅僅是我們擁有的標題元素。我們有一個標題元素,從 開始h1,直到 ,h6唯一的區別是h1較大,然后尺寸減小,直到 h6。
如果您想了解有關 HTML 元素的更多信息,可以在此處查看。
<table>
<tr>
<th>S.No.</th>
<th>Day</th>
</tr>
<tr>
<td>1</td>
<td>Sunday</td>
</tr>
<tr>
<td>2</td>
<td>Monday</td>
</tr>
<tr>
<td>3</td>
<td>Tuesday</td>
</tr>
<tr>
<td>4</td>
<td>Wednesday</td>
</tr>
<tr>
<td>5</td>
<td>Thursday</td>
</tr>
<tr>
<td>6</td>
<td>Friday</td>
</tr>
<tr>
<td>7</td>
<td>Saturday</td>
</tr>
</table>
table:這是用于創建表格的表格元素。
tr:表示表格行。即表的行。
td:表示表數據。即包含該表的數據。
您可以在此處查看代碼的實時版本。
注意此代碼必須寫在body元素之間。
當您上網時,您可能見過一些 HTML 表單。讓我們來創建我們自己的 HTML 表單。
這是代碼片段。
<form>
Name: <input type="text" name="name"><br>
Email: <input type="email" name="email"><br>
<input type="submit" value="Submit">
</form>
form:HTML 元素幫助我們創建 HTML 表單。
input:輸入元素允許我們獲取用戶的輸入。和稱為HTML 屬性type="email"。name="email"
您可以在此處查看該網頁的實時版本。
注意此代碼必須寫在body元素之間。
總之,HTML 通過定義其結構作為網站或網頁的基礎。它決定了網站在標題、表單、表格、按鈕等元素方面的顯示方式。通過使用 HTML 標簽和元素,我們可以創建結構良好且組織良好的網頁。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。