WebMagichtml
WebMagic是一個簡單靈活的Java爬蟲框架。基於WebMagic,你能夠快速開發出一個高效、易維護的爬蟲。java
採用HttpClient能夠實現定向的爬蟲,也能夠本身編寫算法邏輯來實現多線程,建立連接池,自動解析網頁代碼獲取請求連接,封裝正則表達式等等。web
可是若是使用框架,就再也不須要考慮爬蟲的邏輯,只須要專一HTML內容的解析和獲取。正則表達式
引用WebMagic後寫一個爬蟲只須要編寫一個類實現PageProcessor接口,實現兩個方法。算法
一個WebMagic例子瀏覽器
package csdnblog; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.processor.PageProcessor; public class MyPageProcessor implements PageProcessor { @Override public Site getSite() { // 重試3次,抓取間隔1S return Site.me().setRetryTimes(3).setSleepTime(1000); } @Override public void process(Page page) { page.addTargetRequests(page.getHtml().links().regex("http://blog\\.csdn\\.net/\\?&page=.*").all()); try { // 建立新文件 String path = "D:\\testFile\\"+getFileName(page.getUrl().toString())+".html"; PrintWriter printWriter = new PrintWriter(new FileWriter(new File(path))); // 寫內容 printWriter.write(page.getHtml().toString()); printWriter.close(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { Spider.create(new MyPageProcessor()).addUrl("http://blog.csdn.net").thread(5).run(); } public String getFileName(String url) { return url.substring(20, url.length()).replace("?", "").replace("&", ""); } }
這個例子裏實現了一個getSite方法,用來獲取抓取網站的相關配置,包括:編碼、抓取間隔、重試次數等多線程
還實現了一個process方法,裏面除了寫文件的部分,就只有一個page.addTargetRequests(),它是用來爲連接池添加爬蟲須要的連接,當爬蟲線程開啓後,每一個線程會到連接池中取連接,當連接池爲空,爬蟲結束。框架
page.addTargetRequests(page.getHtml().links().regex("http://blog\\.csdn\\.net/\\?&page=.*").all());
即將全部符合"http:blog.csdn.net?&page=數字"的連接放入連接池中ide
例子中能夠看到page.getHtml()即獲取頁面上HTML內容,在此基礎上用xpath就能夠取得其中想要的數據post
xpath是一種HTML標籤元素的路徑表達方式
使用火狐firebug和谷歌瀏覽器F12均可以右鍵標籤直接複製標籤的xpath
能夠採用xpath的方式獲取連接池連接
// 添加全部文章頁 page.addTargetRequests(page.getHtml().xpath("//div[@class='blog_list_wrap']").links()// 限定文章列表獲取區域 .regex("http://blog\\.csdn\\.net/.*/article/details/.*") .all()); // 添加其餘列表頁 page.addTargetRequests(page.getHtml().xpath("//div[@class='page_nav']").links()// 限定其餘列表頁獲取區域 .regex("http://blog\\.csdn\\.net.*") .all());
使用xpath獲取頁面中想要的數據
package csdnblog; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.processor.PageProcessor; public class MyPageProcessor implements PageProcessor { @Override public Site getSite() { // 重試3次,抓取間隔1S return Site.me().setRetryTimes(3).setSleepTime(1000); } @Override public void process(Page page) { // 添加全部文章頁 page.addTargetRequests(page.getHtml().xpath("//div[@class='blog_list_wrap']").links()// 限定文章列表獲取區域 .regex("http://blog\\.csdn\\.net/.*/article/details/.*") .all()); // 添加其餘列表頁 page.addTargetRequests(page.getHtml().xpath("//div[@class='page_nav']").links()// 限定其餘列表頁獲取區域 .regex("http://blog\\.csdn\\.net.*") .all()); //若是當前頁爲文章頁 if(page.getUrl().regex("http://blog\\.csdn\\.net/.*/article/details/.*").match()){ // 編號 System.out.println("編號:" + page.getUrl().regex("http://blog\\.csdn\\.net/.*/article/details/(\\d+)").get()); // 標題 System.out.println("標題:" + page.getHtml().xpath("//div[@class='article_title']//span[@class='link_title']/a/text()").get()); // 日期 System.out.println("日期" + page.getHtml().xpath("//div[@class='article_r']/span[@class='link_postdate']/text()").get()); // 標籤 System.out.println("標籤" + page.getHtml().xpath("//div[@class='article_l']/span[@class='link_categories']/a/allText()").all().toString()); // 類別 System.out.println("類別" + page.getHtml().xpath("//div[@class='category_r']/label/span/text()").all().toString()); } } public static void main(String[] args) { Spider.create(new MyPageProcessor()).addUrl("http://blog.csdn.net").thread(5).run(); } }