這是 Java 網絡爬蟲系列文章的第一篇,若是你還不知道 Java 網絡爬蟲系列文章,請參看 學 Java 網絡爬蟲,須要哪些基礎知識。第一篇是關於 Java 網絡爬蟲入門內容,在該篇中咱們以採集虎撲列表新聞的新聞標題和詳情頁爲例,須要提取的內容以下圖所示:css
咱們須要提取圖中圈出來的文字及其對應的連接,在提取的過程當中,咱們會使用兩種方式來提取,一種是 Jsoup 的方式,另外一種是 httpclient + 正則表達式的方式,這也是 Java 網絡爬蟲經常使用的兩種方式,你不瞭解這兩種方式不要緊,後面會有相應的使用手冊。在正式編寫提取程序以前,我先交代一下 Java 爬蟲系列博文的環境,該系列博文全部的 demo 都是使用 SpringBoot 搭建的,無論你使用哪一種環境,只須要正確的導入相應的包便可。html
咱們先來使用 Jsoup 的方式提取新聞信息,若是你還不知道 Jsoup ,請參考 jsoup.org/java
先創建一個 Springboot 項目,名字就隨意啦,在 pom.xml 中引入 Jsoup 的依賴git
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
複製代碼
好了,接下來咱們一塊兒分析頁面吧,想必你還沒瀏覽過吧,點擊這裏瀏覽虎撲新聞。在列表頁中,咱們利用 F12 審查元素查看頁面結構,通過咱們分析發現列表新聞在 <div class="news-list">
標籤下,每一條新聞都是一個li
標籤,分析結果以下圖所示:github
因爲咱們前面已經知道了 css 選擇器,咱們結合瀏覽器的 Copy 功能,編寫出咱們 a
標籤的 css 選擇器代碼:div.news-list > ul > li > div.list-hd > h4 > a
,一切都準備好了,咱們一塊兒來編寫 Jsoup 方式提取信息的代碼:正則表達式
/** * jsoup方式 獲取虎撲新聞列表頁 * @param url 虎撲新聞列表頁url */ public void jsoupList(String url){ try { Document document = Jsoup.connect(url).get(); // 使用 css選擇器 提取列表新聞 a 標籤 // <a href="https://voice.hupu.com/nba/2484553.html" target="_blank">霍華德:夏休期內曾節食30天,這考驗了個人身心</a> Elements elements = document.select("div.news-list > ul > li > div.list-hd > h4 > a"); for (Element element:elements){ // System.out.println(element); // 獲取詳情頁連接 String d_url = element.attr("href"); // 獲取標題 String title = element.ownText(); System.out.println("詳情頁連接:"+d_url+" ,詳情頁標題:"+title); } } catch (IOException e) { e.printStackTrace(); } } 複製代碼
使用 Jsoup 方式提取仍是很是簡單的,就五、6行代碼就完成了,關於更多 Jsoup 如何提取節點信息的方法能夠參考 jsoup 的官網教程。咱們編寫 main 方法,來執行 jsoupList 方法,看看 jsoupList 方法是否正確。數據庫
public static void main(String[] args) { String url = "https://voice.hupu.com/nba"; CrawlerBase crawlerBase = new CrawlerBase(); crawlerBase.jsoupList(url); } 複製代碼
執行 main 方法,獲得以下結果:apache
從結果中能夠看出,咱們已經正確的提取到了咱們想要的信息,若是你想採集詳情頁的信息,只須要編寫一個採集詳情頁的方法,在方法中提取詳情頁相應的節點信息,而後將列表頁提取的連接傳入提取詳情頁方法便可。上面咱們使用了 Jsoup 方式正確提取了虎撲列表新聞,接下來咱們使用 httpclient + 正則表達式的方式來提取,看看使用這種方式又會涉及到哪些問題?httpclient + 正則表達式的方式涉及的知識點仍是蠻多的,它涉及到了正則表達式、Java 正則表達式、httpclient。若是你還不知道這些知識,能夠點擊下方連接簡單瞭解一下:瀏覽器
正則表達式:正則表達式微信
Java 正則表達式:Java 正則表達式
httpclient:httpclient
咱們在 pom.xml 文件中,引入 httpclient 相關 Jar 包
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.10</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.10</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.10</version>
</dependency>
複製代碼
關於虎撲列表新聞頁面,咱們在使用 Jsoup 方式的時候進行了簡單的分析,這裏咱們就不在重複分析了。對於使用正則表達式方式提取,咱們須要找到可以表明列表新聞的結構體,好比:<div class="list-hd"> <h4> <a href="https://voice.hupu.com/nba/2485508.html" target="_blank">直上雲霄!魔術官方社媒曬富爾茨扣籃炫酷特效圖</a></h4></div>
這段結構體,每一個列表新聞只有連接和標題不同,其餘的都同樣,並且 <div class="list-hd">
是列表新聞特有的。最好不要直接正則匹配 a
標籤,由於 a
標籤在其餘地方也有,這樣咱們就還須要作其餘的處理,增長咱們的難度。如今咱們瞭解了正則結構體的選擇,咱們一塊兒來看看 httpclient + 正則表達式方式提取的代碼:
/** * httpclient + 正則表達式 獲取虎撲新聞列表頁 * @param url 虎撲新聞列表頁url */ public void httpClientList(String url){ try { CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); CloseableHttpResponse response = httpclient.execute(httpGet); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity entity = response.getEntity(); String body = EntityUtils.toString(entity,"utf-8"); if (body!=null) { /* * 替換掉換行符、製表符、回車符,去掉這些符號,正則表示寫起來更簡單一些 * 只有空格符號和其餘正常字體 */ Pattern p = Pattern.compile("\t|\r|\n"); Matcher m = p.matcher(body); body = m.replaceAll(""); /* * 提取列表頁的正則表達式 * 去除換行符以後的 li * <div class="list-hd"> <h4> <a href="https://voice.hupu.com/nba/2485167.html" target="_blank">與球迷親切互動!凱爾特人官方曬球隊開放訓練日照片</a> </h4> </div> */ Pattern pattern = Pattern .compile("<div class=\"list-hd\">\\s* <h4>\\s* <a href=\"(.*?)\"\\s* target=\"_blank\">(.*?)</a>\\s* </h4>\\s* </div>" ); Matcher matcher = pattern.matcher(body); // 匹配出全部符合正則表達式的數據 while (matcher.find()){ // String info = matcher.group(0); // System.out.println(info); // 提取出連接和標題 System.out.println("詳情頁連接:"+matcher.group(1)+" ,詳情頁標題:"+matcher.group(2)); } }else { System.out.println("處理失敗!!!獲取正文內容爲空"); } } else { System.out.println("處理失敗!!!返回狀態碼:" + response.getStatusLine().getStatusCode()); } }catch (Exception e){ e.printStackTrace(); } } 複製代碼
從代碼的行數能夠看出,比 Jsoup 方式要多很多,代碼雖然多,可是總體來講比較簡單,在上面方法中我作了一段特殊處理,我先替換了 httpclient 獲取的字符串 body 中的換行符、製表符、回車符,由於這樣處理,在編寫正則表達式的時候可以減小一些額外的干擾。接下來咱們修改 main 方法,運行 httpClientList 方法。
public static void main(String[] args) { String url = "https://voice.hupu.com/nba"; CrawlerBase crawlerBase = new CrawlerBase(); // crawlerBase.jsoupList(url); crawlerBase.httpClientList(url); } 複製代碼
運行結果以下圖所示:
使用 httpclient + 正則表達式的方式一樣正確的獲取到了列表新聞的標題和詳情頁連接。到此 Java 爬蟲系列博文第一篇就寫完了,這一篇主要是 Java 網絡爬蟲的入門,咱們使用了 jsoup 和 httpclient + 正則的方式提取了虎撲列表新聞的新聞標題和詳情頁連接。固然這裏還有不少沒有完成,好比採集詳情頁信息存入數據庫等。
但願以上內容對你有所幫助,下一篇是模擬登錄相關的,若是你對 Java 網絡爬蟲感興趣,不妨關注一波,一塊兒學習,一塊兒進步。
源代碼:點擊這裏
文章不足之處,望你們多多指點,共同窗習,共同進步
打個小廣告,歡迎掃碼關注微信公衆號:「平頭哥的技術博文」,一塊兒進步吧。