webmagic是Java語言用於爬蟲的工具。官網地址:http://webmagic.io/,中文文檔地址:http://webmagic.io/docs/zh/
使用webmagic有3種配置需要注意,日志配置(log4j),webmagic爬取配置(如超時時間),使用數據庫的話數據庫連接池配置。有一些配置最好做到可以隨機器性能情況而改變配置信息。這樣做的目的是為了將項目打成包以后在命令行下執行程序可以隨時更改配置。因此有些配置文件就不像c3p0配置文件一樣放在源碼文件夾下,而是相對與項目路徑來說。
webmagic的架構圖如下:

從該架構圖上可以得到一個信息,對於每一個頁面來說,都會經歷一個完成的過程,即從downloader--->pipeline,如列表頁也會進入pipeline,所以列表頁雖然沒有數據需要存儲,但在pipeline中去拿值就會出現空指針,因此在pipeline中要先進行判斷,有值的情況下在進行數據庫存儲操作。
在頁面解析部分(待補充),webmagic將解析語法做了一些改變,
1、如將正則表達式中.用\.表示
2、*變成了.*,直接使用表示通配符
3、xpath語法也進行了擴充。
代碼示例:
webmagic版本:0.6.0
package com.lh.pipeline; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import us.codecraft.webmagic.ResultItems; import us.codecraft.webmagic.Task; import us.codecraft.webmagic.pipeline.Pipeline; public class MysqlPipeline implements Pipeline { //有一個容器 static DataSource ds = new ComboPooledDataSource();//直接使用即可,不用顯示的配置,其會自動識別配置文件 public void process(ResultItems resultItems, Task task) { //每進來一次代表一條記錄 //如果容器值達到1000,存一次數據庫並將數據清空,否則將數據存入容器 Map<String, Object> m = resultItems.getAll(); if(!m.isEmpty()){ Set<Entry<String, Object>> set = m.entrySet(); Iterator<Entry<String, Object>> reconds = set.iterator(); String url = null; String name = null; String content = null; for(int i=0;i<set.size();i++){ Entry<String, Object> recond =reconds.next(); if(i==0){ url = recond.getValue().toString(); }else if(i==1){ name = recond.getValue().toString(); }else if(i==2){ content = recond.getValue().toString(); } } Connection conn = null; try { conn = ds.getConnection(); String sql = "insert into softList(url,name,content) values(?,?,?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, url); pstmt.setString(2, name); pstmt.setString(3, content); pstmt.execute(); pstmt.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
package com.lh.spider; import com.lh.pipeline.MysqlPipeline; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.pipeline.FilePipeline; import us.codecraft.webmagic.processor.PageProcessor; public class ProgramSpider implements PageProcessor { private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(10000); public static final String URL_LIST = "http://www\\.xiazaiba\\.com/downlist/187_\\d{1,4}\\.html"; public static final String URL_POST = "http://www\\.xiazaiba\\.com/html/\\d+.html"; public void process(Page page) { if(page.getUrl().regex("http://www\\.xiazaiba\\.com/downlist/187\\.html").match()||page.getUrl().regex(URL_LIST).match()){ //第一頁 //加入詳情頁 //加入列表頁 page.addTargetRequests(page.getHtml().xpath("//ul[@class='cur-cat-list']/li/a[1]").links().all()); page.addTargetRequests(page.getHtml().xpath("//div[@class='ylmf-page']").links().all()); }else{ //詳情頁 page.putField("url", page.getUrl()); page.putField("ProgramName", page.getHtml().xpath("//div[@class='soft-title']/html()")); page.putField("ProgramContent", page.getHtml().xpath("//td[@class='soft-content']/html()")); } } public Site getSite() { return site; } public static void main(String[] args) { Spider.create(new ProgramSpider()) .addUrl("http://www.xiazaiba.com/downlist/187.html") .addPipeline(new MysqlPipeline()).thread(10) .run(); } }
