JAVA爬蟲挖取CSDN博客文章。本站提示廣大學習愛好者:(JAVA爬蟲挖取CSDN博客文章)文章只能為提供參考,不一定能成為您想要的結果。以下是JAVA爬蟲挖取CSDN博客文章正文
之前寫過一篇用jsoup爬取csdn博客的文章JAVA爬蟲挖取CSDN博客文章,事先博主還在上一家公司實習,由於公司辦公網絡需求代理才干訪問外網,那一篇的代碼邏輯與代理親密相關,能夠有些不熟習jsoup怎樣運用的冤家看了會覺得越看越懵懂,且事先以為爬取一切文章需求用到分頁,能夠會誤導讀者。所以明天再次整理那個篇博客的思緒,在沒有代理的網絡的環境下完成代碼功用,假如你的也是處在代理才干訪問外網的網絡,那麼參考本文最後一段的處理方案。
思緒和步驟還是以《第一行代碼--安卓》的作者為例,將他在csdn發表的博客信息都挖取出來,由於郭神是我在大學時期比擬崇敬的對象之一。郭神的博客地址為郭霖博客
在入手實驗之前,假定你曾經根本掌握了如下的技藝:JAVA根底編程,復雜的正則表達式,JS或許jQuery的編程才能,此外還學過http協議的一些知識。假如你還未掌握正則表達式,可以去我的JAVA正則表達式詳解博客看看,假如你還沒有掌握jQuery的根底知識,可以去我的jQuery實戰專欄入手實驗一番。假如上訴技藝你都掌握了,那麼就只差一個jsoup了,這個哥們是干嘛使的呢?用一句話來描繪:這哥們能使Java順序像jQuery那樣的語法來操作html的Dom節點元素,jsoup也有像jQuery一樣的選擇器功用,比方getElementById,getElemementsByClass等語法與JavaScript像極了,此外jsoup還有select選擇器功用。所以,這裡只需略微掌握jsoup語法就可以像JS操作Dom一樣的用Java來處置懇求到的html網頁。jsoup的中文官方教程地址http://www.open-open.com/jsoup/。
工欲善其事必先利其器。開端之前,你應該有一定的工具,比方一款熟習的ide,用來調試和檢查變量。一個web調試工具,如火狐的firebug之類的。總之,就是有一個java web順序員日常開發和調試運用的工具就差不多了。
第一步:新建一個Java Se項目。這個項目假如是一個Maven項目,那麼需求添加如下的依賴配置:
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.10.2</version> </dependency>
假如這個項目不是Maven項目,那麼你需求下載jsoup-1.10.2.jar包,然後在你的項目右鍵新建一個lib目錄,把下載的jar包放出來,並把jar包添加到classpath。
第二步:剖析代碼編寫思緒:先創立一個Conection鏈接,這個鏈接包括向CSDN服務器發起懇求的url地址,userAgent參數,timeOut參數曾經Http懇求類型等。接著向服務器發送get懇求Document doc = conn.get();留意:很多網絡緣由招致這一步呈現異常,比方timeOut時間設置太短也會報錯,這裡我設置為5000毫秒。假如這一步你的順序沒有報錯,闡明曾經獲取了懇求的html文檔。然後我們可以將html的body標簽外面的內容賦值給遍歷Element數據類型的實例body。處置body標簽的內容jsoup正式出場,除了jsoup還會夾雜復雜的正則內容。
用firebug可以看到。首頁與博客文章相關的內容在這個div class="list_item_new"標簽上面,而這個div上面包括3個div,辨別是:div id="article_toplist" class="list"表示置頂的文章,div id="article_list" class="list"博文列表所在的div,div id="papelist" class="pagelist"底下分頁信息所在的div。拋開置頂這個div,我們只關注文章列表的div和分頁信息div。假如你細心的剖析,那麼會發現我們關懷的每篇文章而每篇文章的標簽如下div:`
每篇文章占據的div,完好的html元素如下:
<div class="list_item article_item"> <div class="article_title"> <span class="ico ico_type_Original"></span> <h1> <span class="link_title"><a href="/guolin_blog/article/details/51336415"> Android提示微技巧,你真的理解Dialog、Toast和Snackbar嗎? </a></span> </h1> </div> <div class="article_description"> Dialog和Toast一切人一定都不會生疏的,這個我們平常用的真實是太多了。而Snackbar是Design Support庫中提供的新控件,有些冤家能夠曾經用過了,有些冤家能夠還沒去理解。但是你真的知道什麼時分應該運用Dialog,什麼時分應該運用Toast,什麼時分應該運用Snackbar嗎?本篇文章中我們就來學習一下這三者運用的機遇,另外還會引見一些額定的技巧... </div> <div class="article_manage"> <span class="link_postdate">2016-07-26 07:55</span> <span class="link_view" title="閱讀次數"><a href="/guolin_blog/article/details/51336415" title="閱讀次數">閱讀</a>(7458)</span> <span class="link_comments" title="評論次數"><a href="/guolin_blog/article/details/51336415#comments" title="評論次數" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">評論</a>(45)</span> </div> <div class="clear"></div> </div>
細心剖析一下,這個div中涵蓋了文章的簡介,閱讀次數,銜接地址等等,總之,這個div才是重頭戲要獲取的數據都在這呢。
import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; /** * java爬取csdn博客的復雜的案例,假如你只爬取某個博主的首頁文章,那麼參考本順序員 * 假如你想爬取某位博主的一切文章,請參考Main.java * @author shizongger * @date 2017/02/09 */ public class Main1 { //需求停止爬獲得博客首頁 // private static final String URL = "http://blog.csdn.net/guolin_blog"; private static final String URL = "http://blog.csdn.net/sinyu890807/article/list/2"; public static void main(String[] args) throws IOException { //獲取url地址的http鏈接Connection Connection conn = Jsoup.connect(URL) //博客首頁的url地址 .userAgent("Mozilla/5.0 (Windows NT 6.1; rv:47.0) Gecko/20100101 Firefox/47.0") //http懇求的閱讀器設置 .timeout(5000) //http銜接時長 .method(Connection.Method.GET); //懇求類型是get懇求,http懇求還是post,delete等方式 //獲取頁面的html文檔 Document doc = conn.get(); Element body = doc.body(); //將爬取出來的文章封裝到Artcle中,並放到ArrayList外面去 List<Article> resultList = new ArrayList<Article>(); Element articleListDiv = body.getElementById("article_list"); Elements articleList = articleListDiv.getElementsByClass("list_item"); for(Element article : articleList){ Article articleEntity = new Article(); Element linkNode = (article.select("div h1 a")).get(0); Element desptionNode = (article.getElementsByClass("article_description")).get(0); Element articleManageNode = (article.getElementsByClass("article_manage")).get(0); articleEntity.setAddress(linkNode.attr("href")); articleEntity.setTitle(linkNode.text()); articleEntity.setDesption(desptionNode.text()); articleEntity.setTime(articleManageNode.select("span:eq(0").text()); resultList.add(articleEntity); } //遍歷輸入ArrayList外面的爬取到的文章 System.out.println("文章總數:" + resultList.size()); for(Article article : resultList) { System.out.println("文章相對路勁地址:http://blog.csdn.net" + article.getAddress()); } } }
如今可以將以後頁數的文章發掘出來了,但是郭神的技術文章不止一頁啊,還要進一步分頁發掘。以前我是想Java的分頁思緒是怎樣寫的,我們可以逆著它的分頁思緒來。但是如今覺得與它怎樣分頁有關,但是假如你理解Java分頁那麼更好的了解接上去怎樣做。
要想爬取它的一切文章,可以對他的博客每一個頁面辨別停止懇求。
首頁地址可以是:
http://blog.csdn.net/guolin_blog
也可以是:
http://blog.csdn.net/guolin_blog/article/list/1
那麼第二頁當前的url地址如下:
http://blog.csdn.net/guolin_blog/article/list/index
index表示懇求的頁數。
如今的義務就是來抓取總頁數了。來來來,我們用firebug看一看。
<div id="papelist" class="pagelist"> <span> 100條 共7頁</span><a href="/sinyu890807/article/list/1">首頁</a> <a href="/sinyu890807/article/list/3">上一頁</a> <a href="/sinyu890807/article/list/1">1</a> <a href="/sinyu890807/article/list/2">2</a> <a href="/sinyu890807/article/list/3">3</a> <strong>4</strong> <a href="/sinyu890807/article/list/5">5</a> <a href="/sinyu890807/article/list/6">...</a> <a href="/sinyu890807/article/list/5">下一頁</a> <a href="/sinyu890807/article/list/7">尾頁</a> </div>
可以看到總頁數位於上訴div下的第一個span標簽,僥幸的是這個div有一個無獨有偶的id號,而這個span與div的關系是父節點與子節點的關系,獲取圖中紅圈內字符串的代碼是"body.getElementById("papelist").select("span:eq(0)").text();"。而span標簽外面的內容" 100條 共7頁"是漢字,空格和數字混合組成,這時分正則表達式閃亮退場。為了選取"共x頁"外面的x的值,正則的語法關鍵代碼是:String regex = ".+共(\d+)頁";
至此,就可以將郭霖的csdn技術博客都可以獲取了。此時你只需求將失掉的信息都封裝好,在需求的時分調用就行了。
完好代碼如下:
Article.java
/** * 文章的JavaBean. * date:2017-02-09 */ public class Article { /** * 文章鏈接的絕對地址 */ private String address; /** * 文章標題 */ private String title; /** * 文章簡介 */ private String desption; /** * 文章發表時間 */ private String time; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDesption() { return desption; } public void setDesption(String desption) { this.desption = desption; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } }
Main.java
import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.jsoup.*; import org.jsoup.nodes.*; import org.jsoup.select.*; import com.shizongger.javaspider.Article; /** * @author shizongger * @date 2017/02/09 */ public class Main { private static final String URL = "http://blog.csdn.net/guolin_blog"; public static void main(String[] args) throws IOException { Connection conn = Jsoup.connect(URL) .userAgent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0") .timeout(5000) .method(Connection.Method.GET); Document doc = conn.get(); Element body = doc.body(); //獲取總頁數 String totalPageStr = body.getElementById("papelist").select("span:eq(0)").text(); String regex = ".+共(\\d+)頁"; totalPageStr = totalPageStr.replaceAll(regex, "$1"); int totalPage = Integer.parseInt(totalPageStr); int pageNow = 1; List<Article> articleList = new ArrayList<Article>(); for(pageNow = 1; pageNow <= totalPage; pageNow++){ articleList.addAll(getArtitcleByPage(pageNow)); } //遍歷輸入博主一切的文章 for(Article article : articleList) { System.out.println("文章標題:" + article.getTitle()); System.out.println("文章相對路勁地址:http://blog.csdn.net" + article.getAddress()); System.out.println("文章簡介:" + article.getDesption()); System.out.println("發表時間:" + article.getTime()); } } public static List<Article> getArtitcleByPage(int pageNow) throws IOException{ Connection conn = Jsoup.connect(URL + "/article/list/" + pageNow) .userAgent("Mozilla/5.0 (Windows NT 6.1; rv:47.0) Gecko/20100101 Firefox/47.") .timeout(5000) .method(Connection.Method.GET); Document doc = conn.get(); Element body = doc.body(); List<Article> resultList = new ArrayList<Article>(); Element articleListDiv = body.getElementById("article_list"); Elements articleList = articleListDiv.getElementsByClass("list_item"); for(Element article : articleList){ Article articleEntity = new Article(); Element linkNode = (article.select("div h1 a")).get(0); Element desptionNode = (article.getElementsByClass("article_description")).get(0); Element articleManageNode = (article.getElementsByClass("article_manage")).get(0); articleEntity.setAddress(linkNode.attr("href")); articleEntity.setTitle(linkNode.text()); articleEntity.setDesption(desptionNode.text()); articleEntity.setTime(articleManageNode.select("span:eq(0").text()); resultList.add(articleEntity); } return resultList; } }兩個留意之處
2.當你處於內網時,需求代理才干發送http懇求,在Jsoup.connect(URL)之前,你必需設置代理。
System.setProperty("http.maxRedirects", "50"); System.getProperties().setProperty("proxySet", "true"); String ip = "代理服務器地址"; System.getProperties().setProperty("http.proxyHost", ip); System.getProperties().setProperty("http.proxyPort", "代理的端口");
本文可運轉案例托管在免積分下載地址,本文目的用於技術交流,望與天下Coder共勉!