WebMagic 是干嘛的?
WebMagic 是一个 Java 平台上的开源爬虫框架,其设计参考了 Scrapy,实现则参考了 HttpClient 和 Jsoup。其由四大组件组成:
- Downloader,负责下载网页,使用 HttpClient。
- PageProcessor,负责解析网页和链接发现,使用 Jsoup 和 Xsoup。
- Scheduler,负责管理待抓取的 URL 和去重。
- Pipeline,负责结果数据的持久化。
快速开始
(1)依赖引入
ext { versions = [ "web_magic": '0.7.3' ] } dependencies { // 这里有自己项目的日志实现 compile project(':base') compile("us.codecraft:webmagic-core:${versions.web_magic}") { exclude group: 'org.slf4j', module: 'slf4j-log4j12' // 移除默认的日志实现 } compile("us.codecraft:webmagic-extension:${versions.web_magic}") { exclude group: 'org.slf4j', module: 'slf4j-log4j12' } }
(2)快速开始
爬取 https://github.com/code4craft/ 页面上可以发现的所有 Github 仓库信息。
public class GithubRepoPageProcessor implements PageProcessor { private Site site = Site.me().setRetryTimes(3).setSleepTime(200).setTimeOut(10000); @Override public void process(Page page) { String regex = "(https://github\\.com/code4craft/([\\w-_]+)/)"; page.addTargetRequests(page.getHtml() .links() .regex(regex) .all()); if(!Pattern.matches(regex,page.getUrl().get())){ //skip this page page.setSkip(true); } page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString()); page.putField("name", page.getHtml() .xpath("//meta[@property='og:title']/@content") .toString()); if (page.getResultItems().get("name") == null) { page.setSkip(true); } // page.putField("readme", page.getHtml().xpath("//div[@id='readme']/tidyText()")); } @Override public Site getSite() { return site; } public static void main(String[] args) { Spider.create(new GithubRepoPageProcessor()) .addUrl("https://github.com/code4craft/") .thread(5) .run(); } }
更进一步
Pipeline 接口参数分析
Pipeline 接口会在每个 Page 解析完成之后回调一次。其中的参数如下:
(1)Task
{ "exitWhenComplete": true, "pageCount": 0, // 抓取的第几页 "scheduler": { "duplicateRemover": {} }, "site": { "acceptStatCode": [ 200 ], "allCookies": {}, "cookies": {}, "cycleRetryTimes": 0, "disableCookieManagement": false, "domain": "github.com", "headers": { ":method": "GET", "origin": "https://github.com" }, "retrySleepTime": 1000, "retryTimes": 3, "sleepTime": 100, "timeOut": 10000, "useGzip": true }, "spawnUrl": true, "startTime": 1544165065094, "status": "Running", "threadAlive": 1, "uUID": "github.com" }
(2)ResultItems
{ "all": { // 自定义的字段在这里 "a_key":"a_value" }, "request": { "binaryContent": false, "cookies": {}, "headers": {}, "priority": 0, "url": "https://github.com/code4craft?tab=repositories" }, "skip": false }
排错
Https下无法抓取只支持TLS1.2的站点
作者 code4craft 针对 ISSUE 701 提供了如下的解决方案:
更新会在0.7.4版本发布。 临时适配方式,修改HttpClientGenerator中的buildSSLConnectionSocketFactory方法, return new SSLConnectionSocketFactory(createIgnoreVerifySSL(), new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"}, null, new DefaultHostnameVerifier()) 重写自己实现的HttpClientDownloader,并设置到Spider中。
java.net.UnknownHostException
请检查网络连接。