Crawler4j 快速入門
阿新 • • 發佈:2019-02-16
crawler4j是Java實現的開源網路爬蟲。提供了簡單易用的介面,可以在幾分鐘內建立一個多執行緒網路爬蟲
crawler4j中用了slf4j來記錄專案執行日誌資訊。我們使用slf4j具體實現類log4j
建立一個maven專案。在pom.xml貼上所需jar
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> <scope>test</scope> </dependency> <dependency> <groupId>edu.uci.ics</groupId> <artifactId>crawler4j</artifactId> <version>4.2</version> </dependency>
在resources下貼上log4j.properties
log4j.rootLogger = debug,D,E ### debug ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File = c://logs/log.log log4j.appender.D.Append = true log4j.appender.D.Threshold = DEBUG log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### error ### log4j.appender.E = org.apache.log4j.DailyRollingFileAppender log4j.appender.E.File =c://logs/error.log log4j.appender.E.Append = true log4j.appender.E.Threshold = ERROR log4j.appender.E.layout = org.apache.log4j.PatternLayout log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ]
編寫爬蟲類
package com.gcx.crawler; import edu.uci.ics.crawler4j.crawler.Page; import edu.uci.ics.crawler4j.crawler.WebCrawler; import edu.uci.ics.crawler4j.parser.HtmlParseData; import edu.uci.ics.crawler4j.url.WebURL; import java.util.Set; import java.util.regex.Pattern; /** * 自定義爬蟲類myCrawler需要繼承WebCrawler,決定哪些url被爬取以及處理爬的頁面資訊 */ public class MyCrawler extends WebCrawler { /** * 正則匹配指定的字尾檔案 */ private final static Pattern FILTERS= Pattern.compile(".*(\\.(css|js|gif|jpg|png|mp3|zip|gz))$"); /** * 根據url進行網頁的解析,對返回為TRUE的網頁進行抓取 * 第一個引數referringPage封裝了當前爬取的頁面資訊 * 第二個引數封裝了當前爬取頁面的url資訊 */ @Override public boolean shouldVisit(Page referringPage, WebURL url) { //小寫url String href=url.getURL().toLowerCase(); //正則匹配,過濾掉我們不需要的字尾檔案 return !FILTERS.matcher(href).matches()//匹配過濾掉不需要的字尾檔案 && href.startsWith("http://www.bjsxt.com");//url必須是http://www.baidu.com開頭 } /** * 解析網頁內容,page類包含了豐富的方法,可以利用這些方法得到網頁的內容和屬性 * 當我們爬取到我們需要的頁面,這個方法會被呼叫,我們可以隨意處理頁面 * page 封裝了所有頁面資訊 * */ @Override public void visit(Page page) { //獲取url String url=page.getWebURL().getURL(); System.out.println("url:"+url); //判斷是否是html資料 if(page.getParseData() instanceof HtmlParseData){ //強制型別轉換,獲取html資料物件 HtmlParseData htmlParseData= (HtmlParseData) page.getParseData(); //獲得頁面純文字 String text=htmlParseData.getText(); //獲得頁面html String html=htmlParseData.getHtml(); //獲取頁面輸出連結 Set<WebURL> links=htmlParseData.getOutgoingUrls(); System.out.println("純文字長度: " + text.length()); System.out.println("html長度: " + html.length()); System.out.println("輸出連結個數: " + links.size()); } } }
寫一個控制器呼叫,我們爬取一個www.bjsxt.com
package com.gcx.crawler;
import edu.uci.ics.crawler4j.crawler.CrawlConfig;
import edu.uci.ics.crawler4j.crawler.CrawlController;
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
/**
* 爬蟲控制器
*/
public class Controller {
public static void main(String[] args) throws Exception {
//定義爬蟲儲存的位置
String crawStorageFoler="d:/crawler";
//定義爬蟲執行緒7個
int numberOfCrawlers=1;
//定義爬蟲配置
CrawlConfig config=new CrawlConfig();
//設定爬蟲檔案儲存位置
config.setCrawlStorageFolder(crawStorageFoler);
//例項化頁面獲取器
PageFetcher pageFetcher=new PageFetcher(config);
//例項化爬蟲機器人配置,比如可以設定user-agent
RobotstxtConfig robotstxtconfig=new RobotstxtConfig();
//例項化爬蟲機器人對目標伺服器的配置,每個網站都有一個robots.txt檔案
//規定了該網站哪些頁面可以爬,哪些頁面禁止爬,該類是對robots.txt規範的實現
RobotstxtServer robotstxtServer=new RobotstxtServer(robotstxtconfig,pageFetcher);
//例項化爬蟲控制器
CrawlController controller=new CrawlController(config,pageFetcher,robotstxtServer);
//配置爬取種子頁面,就是規定從哪裡開始爬,可以配置多個種子頁面
controller.addSeed("http://www.bjsxt.com");
//啟動爬蟲,爬蟲從此刻開始執行爬蟲任務
controller.start(MyCrawler.class,numberOfCrawlers);
}
}
爬取如下:
簡單一個爬蟲例項搞定
當然還提供了基本的例項
package com.gcx.crawler;
import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.crawler.WebCrawler;
import edu.uci.ics.crawler4j.parser.HtmlParseData;
import edu.uci.ics.crawler4j.url.WebURL;
import org.apache.http.Header;
import java.util.Set;
import java.util.regex.Pattern;
/**
* 自定義爬蟲類myCrawler需要繼承WebCrawler,決定哪些url被爬取以及處理爬的頁面資訊
*/
public class MyCrawler extends WebCrawler {
/**
* 正則匹配指定的字尾檔案 指定圖片字尾
*/
private static final Pattern IMAGE_EXTENSIONS = Pattern.compile(".*\\.(bmp|gif|jpg|png)$");
/**
* 這個方法主要是決定哪些url我們需要抓取,返回true表示是我們需要的,返回false表示不是我們需要的Url
* 第一個引數referringPage封裝了當前爬取的頁面資訊
* 第二個引數url封裝了當前爬取的頁面url資訊
*/
@Override
public boolean shouldVisit(Page referringPage, WebURL url) {
String href = url.getURL().toLowerCase(); // 得到小寫的url
// 過濾掉含有圖片字尾的url
if (IMAGE_EXTENSIONS.matcher(href).matches()) {
return false;
}
// 只接受www.bjsxt.com開頭的url
return href.startsWith("http://www.bjsxt.com/");
}
/**
* 當我們爬到我們需要的頁面,這個方法會被呼叫,我們可以盡情的處理這個頁面
* page引數封裝了所有頁面資訊
*/
@Override
public void visit(Page page) {
int docid = page.getWebURL().getDocid(); // 獲取docid url的唯一識別 類似主鍵
String url = page.getWebURL().getURL(); // 獲取url
String domain = page.getWebURL().getDomain(); // 獲取域名
String path = page.getWebURL().getPath(); // 獲取路徑
String subDomain = page.getWebURL().getSubDomain(); // 獲取子域名
String parentUrl = page.getWebURL().getParentUrl(); // 獲取上級Url
String anchor = page.getWebURL().getAnchor(); // 獲取錨點
System.out.println("docid:" + docid);
System.out.println("url:" + url);
System.out.println("domain:" + domain);
System.out.println("path:" + path);
System.out.println("subDomain:" + subDomain);
System.out.println("parentUrl:" + parentUrl);
System.out.println("anchor:" + anchor);
if (page.getParseData() instanceof HtmlParseData) { // 判斷是否是html資料
HtmlParseData htmlParseData = (HtmlParseData) page.getParseData(); // 強制型別轉換,獲取html資料物件
String text = htmlParseData.getText(); // 獲取頁面純文字(無html標籤)
String html = htmlParseData.getHtml(); // 獲取頁面Html
Set<WebURL> links = htmlParseData.getOutgoingUrls(); // 獲取頁面輸出連結
System.out.println("純文字長度: " + text.length());
System.out.println("html長度: " + html.length());
System.out.println("輸出連結個數: " + links.size());
}
Header[] responseHeaders = page.getFetchResponseHeaders(); // 獲取響應頭訊息
if (responseHeaders != null) {
System.out.println("響應的頭訊息");
for (Header header : responseHeaders) {
System.out.println(header.getName() + "+" + header.getValue());
}
}
}
}
package com.gcx.crawler;
import edu.uci.ics.crawler4j.crawler.CrawlConfig;
import edu.uci.ics.crawler4j.crawler.CrawlController;
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
/**
* 爬蟲控制器
*/
public class Controller {
public static void main(String[] args) throws Exception {
String crawlStorageFolder = "d:/crawl"; // 定義爬蟲資料儲存位置
int numberOfCrawlers = 7; // 定義7個爬蟲,也就是7個執行緒
CrawlConfig config = new CrawlConfig(); // 例項化爬蟲配置檔案
config.setCrawlStorageFolder(crawlStorageFolder); // 設定爬蟲檔案儲存位置
/*
* 設定請求的頻率
* 每1000毫秒,也就是兩次請求的間隔至少是1秒
*/
config.setPolitenessDelay(1000);
/*
* 設定請求的網頁的深度(後面專門會講) 設定2 為兩層
* 預設值-1 無限深度
*/
config.setMaxDepthOfCrawling(2);
/*
* 設定爬取的最大網頁數 這裡設定1000 最多爬取1000次
* 預設值是-1,表示無限制
*/
config.setMaxPagesToFetch(1000);
/**
* 是否爬取二進位制檔案,比如圖片,PDF文件,視訊之類的東西 這裡設定false 不爬取
* 預設值true,爬取
*/
config.setIncludeBinaryContentInCrawling(false);
/*
* 這裡可以設定代理
* config.setProxyHost("proxyserver.example.com"); // 代理地址
* config.setProxyPort(8080); // 代理埠
*
* 如果使用代理,也可以設定身份認證 使用者名稱和密碼
* config.setProxyUsername(username); config.getProxyPassword(password);
*/
/*
* 這個配置假如設定成true,當一個爬蟲突然終止或者奔潰,我們可以恢復;
* 預設配置是false;推薦用預設配置,假如設定成true,效能會大打折扣;
*/
config.setResumableCrawling(false);
/*
* 例項化爬蟲控制器
*/
PageFetcher pageFetcher = new PageFetcher(config); // 例項化頁面獲取器
RobotstxtConfig robotstxtConfig = new RobotstxtConfig(); // 例項化爬蟲機器人配置 比如可以設定 user-agent
// 例項化爬蟲機器人對目標伺服器的配置,每個網站都有一個robots.txt檔案 規定了該網站哪些頁面可以爬,哪些頁面禁止爬,該類是對robots.txt規範的實現
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
// 例項化爬蟲控制器
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
/*
* 配置爬蟲種子頁面,就是規定的從哪裡開始爬,可以配置多個種子頁面
*/
controller.addSeed("http://www.bjsxt.com/");
/*
* 啟動爬蟲,爬蟲從此刻開始執行爬蟲任務,根據以上配置
*/
controller.start(MyCrawler.class, numberOfCrawlers);
}
}
執行如下: