最近由於有爬一些招聘網站的招聘信息的須要,而我以前也只是知道有「網絡爬蟲」這個神奇的名詞,具體是什麼、用什麼實現、什麼原理、如何實現比較好都不清楚,所以最近大體研究了一下,固然,研究的並非很深刻,畢竟一個高大上的知識即便站在巨人的肩膀上,也不能兩三天就融會貫通。在這裏先作一個技術儲備吧,具體的疑難知識點、細節等之後一點一點的完善,若是如今不趁熱打鐵,之後再想起來恐怕就沒印象了,那麼以個人懶惰的性格估計就要拋棄對它的愛情了。廢話很少說,讓咱們開始在知識的海洋裏遨遊吧。哎,等等,說到這我忽然想到昨天新記的一首詩感受挺好,給你們分享一下,緩解一下氣氛,再給你們講爬蟲吧:html
君生我未生,我生君已老 君恨我生遲,我恨君生早
君生我未生,我生君已老 恨不生同時,日日與君好
我生君未生,君生我已老 我離君天涯,君隔我海角
我生君未生,君生我已老 化蝶去尋花,夜夜棲芳草 java
是一種按照必定的規則,自動地抓取萬維網信息的程序或者腳本。git
簡單易理解,管理方便。github
Downloader負責從互聯網上下載頁面,以便後續處理。WebMagic默認使用了Apache HttpClient做爲下載工具。web
PageProcessor負責解析頁面,抽取有用信息,以及發現新的連接。WebMagic使用Jsoup做爲HTML解析工具,並基於其開發瞭解析XPath的工具Xsoup。正則表達式
在這四個組件中,PageProcessor
對於每一個站點每一個頁面都不同,是須要使用者定製的部分。數據庫
Scheduler負責管理待抓取的URL,以及一些去重的工做。WebMagic默認提供了JDK的內存隊列來管理URL,並用集合來進行去重。也支持使用Redis進行分佈式管理。apache
除非項目有一些特殊的分佈式需求,不然無需本身定製Scheduler。瀏覽器
Pipeline負責抽取結果的處理,包括計算、持久化到文件、數據庫等。WebMagic默認提供了「輸出到控制檯」和「保存到文件」兩種結果處理方案。網絡
Pipeline
定義告終果保存的方式,若是你要保存到指定數據庫,則須要編寫對應的Pipeline。對於一類需求通常只需編寫一個Pipeline
。
依賴:
1 <dependency> 2 <groupId>us.codecraft</groupId> 3 <artifactId>webmagic-core</artifactId> 4 <version>0.6.1</version> 5 </dependency> 6 <dependency> 7 <groupId>us.codecraft</groupId> 8 <artifactId>webmagic-extension</artifactId> 9 <version>0.6.1</version> 10 </dependency>
簡單代碼:
1 import us.codecraft.webmagic.Page; 2 import us.codecraft.webmagic.Site; 3 import us.codecraft.webmagic.Spider; 4 import us.codecraft.webmagic.processor.PageProcessor; 5 6 public class GithubRepoPageProcessor implements PageProcessor { 7 8 private Site site = Site.me().setRetryTimes(3).setSleepTime(100); 9 10 @Override 11 public void process(Page page) { 12 page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all()); 13 page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString()); 14 page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString()); 15 if (page.getResultItems().get("name")==null){ 16 //skip this page 17 page.setSkip(true); 18 } 19 page.putField("readme", page.getHtml().xpath("//div[@id='readme']/tidyText()")); 20 } 21 22 @Override 23 public Site getSite() { 24 return site; 25 } 26 27 public static void main(String[] args) { 28 Spider.create(new GithubRepoPageProcessor()).addUrl("https://github.com/code4craft").thread(5).run(); 29 }
若是仔細分析這段代碼的邏輯,將其弄明白了,那麼對於一個簡單的爬蟲項目,你就能夠本身寫了。
addUrl
是定義從哪個頁面開始爬取;
addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());是指定抓取html頁面的符合此正則表達式的全部連接url;
page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString是指定抓取h1標籤下的class屬性值爲
entry-title public的子標
籤strong下的a標籤下的文本內容;
tidyText()全部的直接和間接文本子節點,並將一些標籤替換爲換行,使純文本顯示更整潔。固然這也就要求你們也要對正則表達式熟悉了。本文用的是xsoup,Xsoup是基於
Jsoup開發的一款XPath 解析器,以前WebMagic使用的解析器是HtmlCleaner,使用過程存在一些問題。主要問題是XPath出錯定位不許確,而且其不太合理的代碼結構進行定製。而Xsoup更加符 合爬蟲開發的需 要。使人欣喜的是,通過測試,Xsoup的性能比HtmlCleaner要快一倍以上。 基於
,
也難以,
也難以,
經過註解將值賦給model屬性的實體類:
1 @TargetUrl("https://github.com/\\w+/\\w+") 2 @HelpUrl("https://github.com/\\w+") 3 public class GithubRepo { 4 5 @ExtractBy(value = "//h1[@class='entry-title public']/strong/a/text()", notNull = true) 6 private String name; 7 8 @ExtractByUrl("https://github\\.com/(\\w+)/.*") 9 private String author; 10 11 @ExtractBy("//div[@id='readme']/tidyText()") 12 private String readme; 13 }
是一個很是有效的爬蟲開發模式,TargetUrl是咱們最終要抓取的URL,最終想要的數據都來自這裏;而HelpUrl則是爲了發現這個最終URL,咱們須要訪問的頁面。幾乎全部垂直爬蟲的需求,均可以歸結爲對這兩類URL的處理:
提示:
HelpUrl/TargetUrl
模擬瀏覽器請求:
1 public VideoSpider(String url, String proxyStr) { 2 this.client_url = url; 3 String[] tmp = proxyStr.split(":"); 4 HttpHost proxy = new HttpHost(tmp[1].substring(2), Integer.parseInt(tmp[2]), tmp[0]); 5 Site site = Site.me().setRetryTimes(3).setHttpProxy(proxy).setSleepTime(100).setTimeOut(10 * 1000).setCharset("UTF-8") 6 .setUserAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"); 7 8 GPHttpClientDownloader downloader = new GPHttpClientDownloader(); 9 Request request = new Request(this.client_url); 10 11 this.setCookie(request, site, downloader); 12 this.setParameters(request, site, downloader); 13 }
中setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"),jobInfoDaoPipeline, LieTouJobInfo.class)
是模擬火狐、蘋果、谷歌等瀏覽器進行請求將經過實體類LieTouJobInfo來抓取指定的內容並經過數據庫訪問層jobInfoDaoPipeline將相關屬性存入數據庫。
簡單的爬蟲用以上代碼基本就能夠實現,可是咱們要知道,要想真正爬取本身想要的內容,還有一段很長的落要走。由於咱們在抓取數據的時候要考慮到去重、動態頁面的產生、快速的更新頻率、巨大的數據量等等的問題。針對這些問題咱們該怎麼作纔能有效簡單的去解決,這是
一個特別值得探討的問題。就先寫到這吧,若是我研究的有進展了,足以在公司項目中穩定投入使用了,再來完善吧。
最新版:WebMagic-0.6.1
Maven依賴:
<dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-core</artifactId> <version>0.6.1</version> </dependency> <dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-extension</artifactId> <version>0.6.1</version> </dependency>