webcollector是一個開源的Java網絡爬蟲框架。最近的爬蟲改用java寫了,對這一週的工做進行簡要總結。對於內部機制瞭解不深刻,主要側重在應用。html
1、環境搭建java
須要安裝一個webcollector的jar包,從官網上下載bin文件,解壓,根據不一樣IDE的安裝方式進行安裝便可。node
https://github.com/CrawlScript/WebCollectorgit
關於使用,官網上提供了不少的例子,從GitHub上將整個Webcollector的工程下載下來,參照進行編碼。github
我直接在官方提供的工程上面建了個文件夾,進行編碼。web
2、基本使用spring
兩個class,一個Model,一個抓取sql
一、Model類——封裝了要抓取的那些字段數據庫
1 package cn.edu.hfut.dmic.webcollector.example.myCrawler.test; 2 3 public class TongModel { 4 String fullName; 5 String shortName; 6 String time; 7 public String getFullName() { 8 return fullName; 9 } 10 11 public void setFullName(String fullName) { 12 this.fullName = fullName; 13 } 14 15 public String getShortName() { 16 return shortName; 17 } 18 19 public void setShortName(String shortName) { 20 this.shortName = shortName; 21 } 22 23 public String getTime() { 24 return time; 25 } 26 27 public void setTime(String time) { 28 this.time = time; 29 } 30 }
二、Crawl類——定義了抓取規則網絡
1 package cn.edu.hfut.dmic.webcollector.example.myCrawler.test; 2 import cn.edu.hfut.dmic.webcollector.crawler.DeepCrawler; 3 //import cn.edu.hfut.dmic.webcollector.example.util.ProxyCollector; 4 import cn.edu.hfut.dmic.webcollector.example.util.JDBCBase; 5 import cn.edu.hfut.dmic.webcollector.model.Links; 6 import cn.edu.hfut.dmic.webcollector.model.Page; 7 import cn.edu.hfut.dmic.webcollector.net.HttpRequesterImpl; 8 import cn.edu.hfut.dmic.webcollector.net.RandomProxyGenerator; 9 import org.jsoup.nodes.Document; 10 import org.jsoup.nodes.Element; 11 import org.jsoup.select.Elements; 12 import org.springframework.jdbc.core.JdbcTemplate; 13 14 import java.util.List; 15 public class CrawlTong extends DeepCrawler{ 16 JdbcTemplate jdbcTemplate = JDBCBase.getInstance().getTemplete2(); 17 public CrawlTong(String crawlPath){ 18 super(crawlPath); 19 } 20 21 @Override 22 public Links visitAndGetNextLinks(Page page) { 23 Document doc = page.getDoc(); 24 boolean iRedirect = page.getResponse().getRedirect(); 25 if(iRedirect) 26 return null; 27 TongModel tongModel = new TongModel(); 28 Elements elementsAll = doc.getAllElements(); 29 tongModel.setFullName(elementsAll.select("a.v3-branding_logo").text()); 30 tongModel.setShortName(elementsAll.select("a.v3-branding_logo").attr("href")); 31 tongModel.setTime("2010-01-21"); 32 saveToDB(tongModel); 33 return null; 34 } 35 public int saveToDB(TongModel m) 36 { 37 System.out.println(m.getFullName()); 38 System.out.println(m.getShortName()); 39 System.out.println(m.getTime()); 40 String sql = "insert into tong(fullName,shortName,timer) values(?,?,?)"; 41 int updates=jdbcTemplate.update(sql,m.getFullName(),m.getShortName(),m.getTime()); 42 return 0; 43 } 44 public static void main(String[] args) throws Exception{ 45 CrawlTong crawler = new CrawlTong("/tong"); 46 crawler.addSeed("https://www.tzg.cn/"); 47 crawler.start(1); 48 } 49 50 }
繼承自抓取父類,我採用的是繼承DeepCrawler,相應的也能夠繼承自BreathCrawler。
主要是三個方法,當寫完extends DeepCrawler,通常編輯器會提示你實現構造方法和重寫visitAndGetNextLinks方法,而後須要建立一個main函數
(1)main函數,至關於爬蟲的入口
① 新建一個爬蟲
② 設定種子,即要爬取的URL
③ 能夠設定爬取的線程數,crawler.setThreads(1); 能夠並行爬行
④ 設定爬取的深度,crawler.start(10);
關於深度,個人理解是,初始種子是第一層;若是在爬取的過程當中不斷的加入新的URL,經過第一層新加入的就算第二層;以此類推
一般爬取的時候深度很差確認,最簡單的辦法就是設定個特別大的值
(2)visitAndGetNextLinks方法,頁面解析
採用Jsoup的方法,對頁面進行解析 http://www.open-open.com/jsoup/selector-syntax.htm
定義一個Model的對象,經過set的方式把數據存入model
再將Model存放到數據庫中
(3)構造方法
關於構造方法,我目前的應用中基本沒有修改,後續遇到再補充
(4)JdbcTemplate jdbcTemplate = JDBCBase.getInstance().getTemplete2();
這行代碼,是數據庫相關的配置
JDNCBase文件中的getTemplete2(),定義了鏈接哪一個數據庫
補充1:DAO
WebCollector自己融合了Spring框架(不知道這樣說合不合理,自己對Java的框架理解不深),能夠經過DAO的形式對數據進行存儲。
1 package cn.edu.hfut.dmic.webcollector.example.myCrawler.test; 2 3 import cn.edu.hfut.dmic.webcollector.example.util.GenericDaoImpl; 4 5 import java.util.List; 6 7 public class DataVaryDao extends GenericDaoImpl<DataVaryModel,Long> { 8 9 public DataVaryDao(){super(DataVaryModel.class);} 10 11 public Long add(DataVaryModel model) 12 { 13 return insert(model); 14 } 15 16 public int updata(DataVaryModel model) 17 { 18 return this.update(model); 19 } 20 21 public List<DataVaryModel> getDataBySql(String sql, List<Object> values) 22 { 23 return this.selectBySqlList(sql, values); 24 25 } 26 27 @Override 28 public long getCountBySqlList(String sql, List<Object> values) { 29 return 0; 30 } 31 }
1 dataList = dataDao.getDataBySql("select * from table where xmbm = ? and platform_id = ?", valueList); 2 dataModelDB = dataList.get(0); 3 4 dataVaryModel=new DataVaryModel(); 5 dataVaryModel.setData_id(dataModelDB.getId()); 6 dataVaryModel.setKtje(ktje); 7 dataVaryModel.setXmzt(xmzt); 8 dataVaryModel.setTzrc(tzrc); 9 dataVaryModel.setCreate_date(new Timestamp(new Date().getTime())); 10 dataVaryDao.add(dataVaryModel);
上面就是定義了一個簡單的DAO類,這個類也繼承自一個基類;而後經過調用DAO中的方法進行數據存儲
固然DAO對數據的增刪改查等須要本身後臺實現
補充2:動態增長種子
爬取的一個常見狀況,一邊爬網頁,一邊將網頁中的URL加入到爬取隊列中。
1 Links links=new Links(); 2 for(int i=0;i<length;i++){ 3 String temp=pre+elements1.get(i).attr("href"); 4 System.out.println(temp); 5 System.out.println(elements1.get(i).text().trim()); 6 links.add(temp); 7 } 8 9 return links;
在visitAndGetNextLinks方法中,定義一個Links類型的變量,將URL加入變量中,返回便可
如上述說起的爬取深度,爬出初始URL頁面獲取的links就是第二層,一顆樹形的結構,隨着抓取的增長,深度不斷加深
補充3:不動態增長種子,可是爬取新頁面
還有一種狀況,在爬取的過程當中獲得了新的URL,可是不想放入對爬取隊列,想當下就拿到上面的數據。
1 String newUrl="http://www.xueshandai.com/invest/invest-record/"+xmbm; 2 try { 3 System.out.println(newUrl); 4 String html = requester.getResponse(newUrl).getHtml("UTF-8"); 5 Pattern p = Pattern.compile("<div class=\"jtit3\">(.*?)</div>"); 6 Matcher m = p.matcher(html); 7 System.out.println(m); 8 if(m.find()){ 9 System.out.println("------find---------"); 10 String s=m.group().split(":")[3].split("<")[0]; 11 System.out.println(s.substring(0,s.length()-1)); 12 tzrc = Integer.parseInt(s.substring(0,s.length()-1)); 13 } 14 } catch (Exception e) { 15 e.printStackTrace(); 16 }
requester.getResponse(newUrl).getHtml("UTF-8");
經過這樣一條語句,能夠直接獲得url的HTML,不過存儲的是String類型,能夠經過正則進行解析,獲取須要的數據。
補充4:對不一樣種類的URL進行分門處理
可能抓取隊列中存放着不一樣類型的URL,對每一種爬取方案是不一樣的。
高大上的方法:定義抽取器
簡單方法:字符串匹配
if(pageURL.contains("list")){}
else if (pageURL.contains("detail")){}
以上,就是目前遇到的一些狀況,比較簡單,還會再用兩週。
後續內容:
(1)加代理(已經遇到封IP的狀況了)、加頭部文件
(2)抽取器
(3)解析Json文件、XML文件
(4)內部機制的學習調用