Commit ce89ebb2 authored by yihua.huang's avatar yihua.huang

remove en_doc zh_docs dir

parent b9ac76aa
![logo](https://raw.github.com/code4craft/webmagic/master/assets/logo.jpg)
[Readme in Chinese](https://github.com/code4craft/webmagic/tree/master/zh_docs)
[User Manual (Chinese)](https://github.com/code4craft/webmagic/blob/master/user-manual.md)
[![Build Status](https://travis-ci.org/code4craft/webmagic.png?branch=master)](https://travis-ci.org/code4craft/webmagic)
>A scalable crawler framework. It covers the whole lifecycle of crawler: downloading, url management, content extraction and persistent. It can simplify the development of a specific crawler.
## Features:
* Simple core with high flexibility.
* Simple API for html extracting.
* Annotation with POJO to customize a crawler, no configuration.
* Multi-thread and Distribution support.
* Easy to be integrated.
## Install:
Add dependencies to your pom.xml:
```xml
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.5.1</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.5.1</version>
</dependency>
```
WebMagic use slf4j with slf4j-log4j12 implementation. If you customized your slf4j implementation, please exclude slf4j-log4j12.
```xml
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
```
## Get Started:
### First crawler:
Write a class implements PageProcessor. For example, I wrote a crawler of github repository infomation.
```java
public class GithubRepoPageProcessor implements PageProcessor {
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);
@Override
public void process(Page page) {
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());
page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString());
page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString());
if (page.getResultItems().get("name")==null){
//skip this page
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();
}
}
```
* `page.addTargetRequests(links)`
Add urls for crawling.
You can also use annotation way:
```java
@TargetUrl("https://github.com/\\w+/\\w+")
@HelpUrl("https://github.com/\\w+")
public class GithubRepo {
@ExtractBy(value = "//h1[@class='entry-title public']/strong/a/text()", notNull = true)
private String name;
@ExtractByUrl("https://github\\.com/(\\w+)/.*")
private String author;
@ExtractBy("//div[@id='readme']/tidyText()")
private String readme;
public static void main(String[] args) {
OOSpider.create(Site.me().setSleepTime(1000)
, new ConsolePageModelPipeline(), GithubRepo.class)
.addUrl("https://github.com/code4craft").thread(5).run();
}
}
```
### Docs and samples:
Documents: [http://webmagic.io/docs/](http://webmagic.io/docs/)
The architecture of webmagic (refered to [Scrapy](http://scrapy.org/))
![image](http://code4craft.github.io/images/posts/webmagic.png)
Javadocs: [http://code4craft.github.io/webmagic/docs/en/](http://code4craft.github.io/webmagic/docs/en/)
There are some samples in `webmagic-samples` package.
### Lisence:
Lisenced under [Apache 2.0 lisence](http://opensource.org/licenses/Apache-2.0)
### Contributors:
Thanks these people for commiting source code, reporting bugs or suggesting for new feature:
* [ccliangbo](https://github.com/ccliangbo)
* [yuany](https://github.com/yuany)
* [yxssfxwzy](https://github.com/yxssfxwzy)
* [linkerlin](https://github.com/linkerlin)
* [d0ngw](https://github.com/d0ngw)
* [xuchaoo](https://github.com/xuchaoo)
* [supermicah](https://github.com/supermicah)
* [SimpleExpress](https://github.com/SimpleExpress)
* [aruanruan](https://github.com/aruanruan)
* [l1z2g9](https://github.com/l1z2g9)
* [zhegexiaohuozi](https://github.com/zhegexiaohuozi)
* [ywooer](https://github.com/ywooer)
* [yyw258520](https://github.com/yyw258520)
* [perfecking](https://github.com/perfecking)
* [lidongyang](http://my.oschina.net/lidongyang)
* [seveniu](https://github.com/seveniu)
* [sebastian1118](https://github.com/sebastian1118)
* [codev777](https://github.com/codev777)
### Thanks:
To write webmagic, I refered to the projects below :
* **Scrapy**
A crawler framework in Python.
[http://scrapy.org/](http://scrapy.org/)
* **Spiderman**
Another crawler framework in Java.
[https://gitcafe.com/laiweiwei/Spiderman](https://gitcafe.com/laiweiwei/Spiderman)
### Mail-list:
[https://groups.google.com/forum/#!forum/webmagic-java](https://groups.google.com/forum/#!forum/webmagic-java)
[http://list.qq.com/cgi-bin/qf_invite?id=023a01f505246785f77c5a5a9aff4e57ab20fcdde871e988](http://list.qq.com/cgi-bin/qf_invite?id=023a01f505246785f77c5a5a9aff4e57ab20fcdde871e988)
QQ Group: 373225642
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/code4craft/webmagic/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
![logo](https://raw.github.com/code4craft/webmagic/master/assets/logo.jpg)
[![Build Status](https://travis-ci.org/code4craft/webmagic.png?branch=master)](https://travis-ci.org/code4craft/webmagic)
[Readme in English](https://github.com/code4craft/webmagic/tree/master/en_docs)
官方网站[http://webmagic.io/](http://webmagic.io/)
>webmagic是一个开源的Java垂直爬虫框架,目标是简化爬虫的开发流程,让开发者专注于逻辑功能的开发。webmagic的核心非常简单,但是覆盖爬虫的整个流程,也是很好的学习爬虫开发的材料。作者曾经在前公司进行过一年的垂直爬虫的开发,webmagic就是为了解决爬虫开发的一些重复劳动而产生的框架。
>web爬虫是一种技术,webmagic致力于将这种技术的实现成本降低,但是出于对资源提供者的尊重,webmagic不会做反封锁的事情,包括:验证码破解、代理切换、自动登录等。
webmagic的主要特色:
* 完全模块化的设计,强大的可扩展性。
* 核心简单但是涵盖爬虫的全部流程,灵活而强大,也是学习爬虫入门的好材料。
* 提供丰富的抽取页面API。
* 无配置,但是可通过POJO+注解形式实现一个爬虫。
* 支持多线程。
* 支持分布式。
* 支持爬取js动态渲染的页面。
* 无框架依赖,可以灵活的嵌入到项目中去。
webmagic的架构和设计参考了以下两个项目,感谢以下两个项目的作者:
python爬虫 **scrapy** [https://github.com/scrapy/scrapy](https://github.com/scrapy/scrapy)
Java爬虫 **Spiderman** [https://gitcafe.com/laiweiwei/Spiderman](https://gitcafe.com/laiweiwei/Spiderman)
webmagic的github地址:[https://github.com/code4craft/webmagic](https://github.com/code4craft/webmagic)
## 快速开始
### 使用maven
webmagic使用maven管理依赖,在项目中添加对应的依赖即可使用webmagic:
```xml
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.5.2</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.5.2</version>
</dependency>
```
WebMagic 使用slf4j-log4j12作为slf4j的实现.如果你自己定制了slf4j的实现,请在项目中去掉此依赖。
```xml
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
```
#### 项目结构
webmagic主要包括两个包:
* **webmagic-core**
webmagic核心部分,只包含爬虫基本模块和基本抽取器。webmagic-core的目标是成为网页爬虫的一个教科书般的实现。
* **webmagic-extension**
webmagic的扩展模块,提供一些更方便的编写爬虫的工具。包括注解格式定义爬虫、JSON、分布式等支持。
webmagic还包含两个可用的扩展包,因为这两个包都依赖了比较重量级的工具,所以从主要包中抽离出来,这些包需要下载源码后自己编译::
* **webmagic-saxon**
webmagic与Saxon结合的模块。Saxon是一个XPath、XSLT的解析工具,webmagic依赖Saxon来进行XPath2.0语法解析支持。
* **webmagic-selenium**
webmagic与Selenium结合的模块。Selenium是一个模拟浏览器进行页面渲染的工具,webmagic依赖Selenium进行动态页面的抓取。
在项目中,你可以根据需要依赖不同的包。
### 不使用maven
在项目的**lib**目录下,有依赖的所有jar包,直接在IDE里import即可。
### 第一个爬虫
#### 定制PageProcessor
PageProcessor是webmagic-core的一部分,定制一个PageProcessor即可实现自己的爬虫逻辑。以下是抓取osc博客的一段代码:
```java
public class OschinaBlogPageProcesser implements PageProcessor {
private Site site = Site.me().setDomain("my.oschina.net");
@Override
public void process(Page page) {
List<String> links = page.getHtml().links().regex("http://my\\.oschina\\.net/flashsword/blog/\\d+").all();
page.addTargetRequests(links);
page.putField("title", page.getHtml().xpath("//div[@class='BlogEntity']/div[@class='BlogTitle']/h1").toString());
page.putField("content", page.getHtml().$("div.content").toString());
page.putField("tags",page.getHtml().xpath("//div[@class='BlogTags']/a/text()").all());
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) {
Spider.create(new OschinaBlogPageProcesser()).addUrl("http://my.oschina.net/flashsword/blog")
.addPipeline(new ConsolePipeline()).run();
}
}
```
这里通过page.addTargetRequests()方法来增加要抓取的URL,并通过page.putField()来保存抽取结果。page.getHtml().xpath()则是按照某个规则对结果进行抽取,这里抽取支持链式调用。调用结束后,toString()表示转化为单个String,all()则转化为一个String列表。
Spider是爬虫的入口类。Pipeline是结果输出和持久化的接口,这里ConsolePipeline表示结果输出到控制台。
执行这个main方法,即可在控制台看到抓取结果。webmagic默认有3秒抓取间隔,请耐心等待。
#### 使用注解
webmagic-extension包括了注解方式编写爬虫的方法,只需基于一个POJO增加注解即可完成一个爬虫。以下仍然是抓取oschina博客的一段代码,功能与OschinaBlogPageProcesser完全相同:
```java
@TargetUrl("http://my.oschina.net/flashsword/blog/\\d+")
public class OschinaBlog {
@ExtractBy("//title")
private String title;
@ExtractBy(value = "div.BlogContent",type = ExtractBy.Type.Css)
private String content;
@ExtractBy(value = "//div[@class='BlogTags']/a/text()", multi = true)
private List<String> tags;
public static void main(String[] args) {
OOSpider.create(
Site.me(),
new ConsolePageModelPipeline(), OschinaBlog.class).addUrl("http://my.oschina.net/flashsword/blog").run();
}
}
```
这个例子定义了一个Model类,Model类的字段'title'、'content'、'tags'均为要抽取的属性。这个类在Pipeline里是可以复用的。
### 详细文档
[http://webmagic.io/docs/](http://webmagic.io/docs/)
### 示例
webmagic-samples目录里有一些定制PageProcessor以抽取不同站点的例子。
webmagic的使用可以参考:[oschina openapi 应用:博客搬家](http://my.oschina.net/oscfox/blog/194507)
### 协议
webmagic遵循[Apache 2.0协议](http://opensource.org/licenses/Apache-2.0)
### 贡献者:
以下是为WebMagic提交过代码或者issue的朋友:
* [ccliangbo](https://github.com/ccliangbo)
* [yuany](https://github.com/yuany)
* [yxssfxwzy](https://github.com/yxssfxwzy)
* [linkerlin](https://github.com/linkerlin)
* [d0ngw](https://github.com/d0ngw)
* [xuchaoo](https://github.com/xuchaoo)
* [supermicah](https://github.com/supermicah)
* [SimpleExpress](https://github.com/SimpleExpress)
* [aruanruan](https://github.com/aruanruan)
* [l1z2g9](https://github.com/l1z2g9)
* [zhegexiaohuozi](https://github.com/zhegexiaohuozi)
* [ywooer](https://github.com/ywooer)
* [yyw258520](https://github.com/yyw258520)
* [perfecking](https://github.com/perfecking)
* [lidongyang](http://my.oschina.net/lidongyang)
* [seveniu](https://github.com/seveniu)
* [sebastian1118](https://github.com/sebastian1118)
* [codev777](https://github.com/codev777)
* [fengwuze](https://github.com/fengwuze)
### 邮件组:
Gmail:
[https://groups.google.com/forum/#!forum/webmagic-java](https://groups.google.com/forum/#!forum/webmagic-java)
QQ:
[http://list.qq.com/cgi-bin/qf_invite?id=023a01f505246785f77c5a5a9aff4e57ab20fcdde871e988](http://list.qq.com/cgi-bin/qf_invite?id=023a01f505246785f77c5a5a9aff4e57ab20fcdde871e988)
### QQ群:
373225642
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page]]></key>
<data><![CDATA[ <pre class="zh">
Page保存了上一次抓取的结果,并可定义待抓取的链接内容。
主要方法:
{@link #getUrl()} 获取页面的Url
{@link #getHtml()} 获取页面的html内容
{@link #putField(String, Object)} 保存抽取的结果
{@link #getResultItems()} 获取抽取的结果,在 {@link us.codecraft.webmagic.pipeline.Pipeline} 中调用
{@link #addTargetRequests(java.util.List)} {@link #addTargetRequest(String)} 添加待抓取的链接
</pre>
<pre class="en">
Store extracted result and urls to be crawled.
Main method:
{@link #getUrl()} get url of current page
{@link #getHtml()} get content of current page
{@link #putField(String, Object)} save extracted result
{@link #getResultItems()} get extract results to be used in {@link us.codecraft.webmagic.pipeline.Pipeline}
{@link #addTargetRequests(java.util.List)} {@link #addTargetRequest(String)} add urls to fetch
</pre>
@author code4crafter@gmail.com <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.putField(java.lang.String, java.lang.Object)]]></key>
<data><![CDATA[
@param key 结果的key
@param field 结果的value
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.getHtml()]]></key>
<data><![CDATA[ 获取页面的html内容
@return html 页面的html内容
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.addTargetRequests(java.util.List<java.lang.String>)]]></key>
<data><![CDATA[ 添加待抓取的链接
@param requests 待抓取的链接
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.addTargetRequest(java.lang.String)]]></key>
<data><![CDATA[ 添加待抓取的链接
@param requestString 待抓取的链接
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.addTargetRequest(us.codecraft.webmagic.Request)]]></key>
<data><![CDATA[ 添加待抓取的页面,在需要传递附加信息时使用
@param request 待抓取的页面
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.getUrl()]]></key>
<data><![CDATA[ 获取页面的Url
@return url 当前页面的url,可用于抽取
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.setUrl(us.codecraft.webmagic.selector.Selectable)]]></key>
<data><![CDATA[ 设置url
@param url
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Page.getRequest()]]></key>
<data><![CDATA[ 获取抓取请求
@return request 抓取请求
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.MultiPageModel]]></key>
<data><![CDATA[ 实现此接口以进行支持爬虫分页抓取。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-4 <br>
Time: 下午5:18 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.Request]]></key>
<data><![CDATA[ <div class="zh">
Request对象封装了待抓取的url信息。<br/>
在PageProcessor中,Request对象可以通过{@link us.codecraft.webmagic.Page#getRequest()} 获取。<br/>
<br/>
Request对象包含一个extra属性,可以写入一些必须的上下文,这个特性在某些场合会有用。<br/>
<pre>
Example:
抓取<a href="${link}">${linktext}</a>时,希望提取链接link,并保存linktext的信息。
在上一个页面:
public void process(Page page){
Request request = new Request(link,linktext);
page.addTargetRequest(request)
}
在下一个页面:
public void process(Page page){
String linktext = (String)page.getRequest().getExtra()[0];
}
</pre>
</div>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午11:37
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Request(java.lang.String)]]></key>
<data><![CDATA[ 构建一个request对象
@param url 必须参数,待抓取的url
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Request.setPriority(double)]]></key>
<data><![CDATA[ 设置优先级,用于URL队列排序<br>
需扩展Scheduler<br>
目前还没有对应支持优先级的Scheduler实现 =。= <br>
@param priority 优先级,越大则越靠前
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Request.getUrl()]]></key>
<data><![CDATA[ 获取待抓取的url
@return url 待抓取的url
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.ResultItems]]></key>
<data><![CDATA[ 保存抽取结果的类,由PageProcessor处理得到,传递给{@link us.codecraft.webmagic.pipeline.Pipeline}进行持久化。<br>
@author code4crafter@gmail.com <br>
Date: 13-7-25 <br>
Time: 下午12:20 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.ResultItems.isSkip()]]></key>
<data><![CDATA[ 是否忽略这个页面,用于pipeline来判断是否对这个页面进行处理
@return 是否忽略 true 忽略
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.ResultItems.setSkip(boolean)]]></key>
<data><![CDATA[ 设置是否忽略这个页面,用于pipeline来判断是否对这个页面进行处理
@param skip
@return this
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site]]></key>
<data><![CDATA[ Site定义一个待抓取的站点的各种信息。<br>
这个类的所有getter方法,一般都只会被爬虫框架内部进行调用。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午12:13
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.me()]]></key>
<data><![CDATA[ 创建一个Site对象,等价于new Site()
@return 新建的对象
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.addCookie(java.lang.String, java.lang.String)]]></key>
<data><![CDATA[ 为这个站点添加一个cookie,可用于抓取某些需要登录访问的站点。这个cookie的域名与{@link #getDomain()}是一致的
@param name cookie的名称
@param value cookie的值
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.setUserAgent(java.lang.String)]]></key>
<data><![CDATA[ 为这个站点设置user-agent,很多网站都对user-agent进行了限制,不设置此选项可能会得到期望之外的结果。
@param userAgent userAgent
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getCookies()]]></key>
<data><![CDATA[ 获取已经设置的所有cookie
@return 已经设置的所有cookie
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getUserAgent()]]></key>
<data><![CDATA[ 获取已设置的user-agent
@return 已设置的user-agent
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getDomain()]]></key>
<data><![CDATA[ 获取已设置的domain
@return 已设置的domain
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.setDomain(java.lang.String)]]></key>
<data><![CDATA[ 设置这个站点所在域名,必须项。<br>
目前不支持多个域名的抓取。抓取多个域名请新建一个Spider。
@param domain 爬虫会抓取的域名
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.setCharset(java.lang.String)]]></key>
<data><![CDATA[ 设置页面编码,若不设置则自动根据Html meta信息获取。<br>
一般无需设置encoding,如果发现下载的结果是乱码,则可以设置此项。<br>
@param charset 编码格式,主要是"utf-8"、"gbk"两种
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getCharset()]]></key>
<data><![CDATA[ 获取已设置的编码
@return 已设置的domain
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.setAcceptStatCode(java.util.Set<java.lang.Integer>)]]></key>
<data><![CDATA[ 设置可接受的http状态码,仅当状态码在这个集合中时,才会读取页面内容。<br>
默认为200,正常情况下,无须设置此项。<br>
某些站点会错误的返回状态码,此时可以对这个选项进行设置。<br>
@param acceptStatCode 可接受的状态码
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getAcceptStatCode()]]></key>
<data><![CDATA[ 获取可接受的状态码
@return 可接受的状态码
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getStartUrls()]]></key>
<data><![CDATA[ 获取初始页面的地址列表
@return 初始页面的地址列表
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.addStartUrl(java.lang.String)]]></key>
<data><![CDATA[ 增加初始页面的地址,可反复调用此方法增加多个初始地址。
@param startUrl 初始页面的地址
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.setSleepTime(int)]]></key>
<data><![CDATA[ 设置两次抓取之间的间隔,避免对目标站点压力过大(或者避免被防火墙屏蔽...)。
@param sleepTime 单位毫秒
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getSleepTime()]]></key>
<data><![CDATA[ 获取两次抓取之间的间隔
@return 两次抓取之间的间隔,单位毫秒
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.getRetryTimes()]]></key>
<data><![CDATA[ 获取重新下载的次数,默认为0
@return 重新下载的次数
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Site.setRetryTimes(int)]]></key>
<data><![CDATA[ 设置获取重新下载的次数,默认为0
@return this
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider]]></key>
<data><![CDATA[ <pre>
webmagic爬虫的入口类。
示例:
定义一个最简单的爬虫:
Spider.create(new SimplePageProcessor("http://my.oschina.net/", "http://my.oschina.net/*blog/*")).run();
使用FilePipeline保存结果到文件:
Spider.create(new SimplePageProcessor("http://my.oschina.net/", "http://my.oschina.net/*blog/*"))
.pipeline(new FilePipeline("/data/temp/webmagic/")).run();
使用FileCacheQueueScheduler缓存URL,关闭爬虫后下次自动从停止的页面继续抓取:
Spider.create(new SimplePageProcessor("http://my.oschina.net/", "http://my.oschina.net/*blog/*"))
.scheduler(new FileCacheQueueScheduler("/data/temp/webmagic/cache/")).run();
</pre>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午6:53
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider(us.codecraft.webmagic.processor.PageProcessor)]]></key>
<data><![CDATA[ 使用已定义的抽取规则新建一个Spider。
@param pageProcessor 已定义的抽取规则
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider.create(us.codecraft.webmagic.processor.PageProcessor)]]></key>
<data><![CDATA[ 使用已定义的抽取规则新建一个Spider。
@param pageProcessor 已定义的抽取规则
@return 新建的Spider
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider.startUrls(java.util.List<java.lang.String>)]]></key>
<data><![CDATA[ 重新设置startUrls,会覆盖Site本身的startUrls。
@param startUrls
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider.setUUID(java.lang.String)]]></key>
<data><![CDATA[ 为爬虫设置一个唯一ID,用于标志任务,默认情况下使用domain作为uuid,对于单domain多任务的情况,请为重复任务设置不同的ID。
@param uuid 唯一ID
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider.scheduler(us.codecraft.webmagic.scheduler.Scheduler)]]></key>
<data><![CDATA[ 设置调度器。调度器用于保存待抓取URL,并可以进行去重、同步、持久化等工作。默认情况下使用内存中的阻塞队列进行调度。
@param scheduler 调度器
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider.pipeline(us.codecraft.webmagic.pipeline.Pipeline)]]></key>
<data><![CDATA[ 设置处理管道。处理管道用于最终抽取结果的后处理,例如:保存到文件、保存到数据库等。默认情况下会输出到控制台。
@param pipeline 处理管道
@return this
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider.test(java.lang.String...)]]></key>
<data><![CDATA[ 用某些特定URL进行爬虫测试
@param urls 要抓取的url
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Spider.thread(int)]]></key>
<data><![CDATA[ 建立多个线程下载
@param threadNum 线程数
@return this
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.Task]]></key>
<data><![CDATA[ 抓取任务的抽象接口。<br>
@author code4crafter@gmail.com <br>
Date: 13-6-18
Time: 下午2:57
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Task.getUUID()]]></key>
<data><![CDATA[ 返回唯一标志该任务的字符串,以区分不同任务。
@return uuid
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.Task.getSite()]]></key>
<data><![CDATA[ 返回任务抓取的站点信息
@return site
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.Destroyable]]></key>
<data><![CDATA[ 比较占用资源的服务可以实现该接口,Spider会在结束时调用destroy()释放资源。<br>
@author code4crafter@gmail.com <br>
Date: 13-7-26 <br>
Time: 下午3:10 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.Downloader]]></key>
<data><![CDATA[ Downloader是webmagic下载页面的接口。webmagic默认使用了HttpComponent作为下载器,一般情况,你无需自己实现这个接口。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午12:14
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.Downloader.download(us.codecraft.webmagic.Request, us.codecraft.webmagic.Task)]]></key>
<data><![CDATA[ 下载页面,并保存信息到Page对象中。
@param request
@param task
@return page
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.Downloader.setThread(int)]]></key>
<data><![CDATA[ 设置线程数,多线程程序一般需要Downloader支持<br>
如果不考虑多线程的可以不实现这个方法<br>
@param thread 线程数量
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.FileCache]]></key>
<data><![CDATA[ 使用缓存到本地的文件来模拟下载,可以在Spider框架中仅进行抽取工作。<br>
@author code4crafer@gmail.com
Date: 13-6-24
Time: 上午7:24
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.HttpClientDownloader]]></key>
<data><![CDATA[ 封装了HttpClient的下载器。已实现指定次数重试、处理gzip、自定义UA/cookie等功能。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午12:15
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.HttpClientDownloader.download(java.lang.String)]]></key>
<data><![CDATA[ 直接下载页面的简便方法
@param url
@return
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader.HttpClientGenerator]]></key>
<data><![CDATA[ @author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午12:29
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.downloader]]></key>
<data><![CDATA[
包含了页面下载的接口Downloader和实现类HttpClientDownloader,该实现类封装了HttpComponent库。
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.AfterExtractor]]></key>
<data><![CDATA[ 实现这个接口即可在抽取后进行后处理。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-3 <br>
Time: 上午9:42 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.ConsolePageModelPipeline]]></key>
<data><![CDATA[ @author code4crafter@gmail.com <br>
Date: 13-8-3 <br>
Time: 下午3:41 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.HasKey]]></key>
<data><![CDATA[ 标志一个Model的key。<br>
实现了这个接口的Model在输出时会使用getKey()作为标志(例如JsonFilePageModelPipeline中持久化的文件名)。<br>
如果持久化的文件名是乱码,请再运行的环境变量里加上LANG=zh_CN.UTF-8 。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-10 <br>
Time: 上午7:39 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.HasKey.key()]]></key>
<data><![CDATA[ 在输出时会使用key作为标志(例如JsonFilePageModelPipeline中持久化的文件名)。
@return key
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.OOSpider]]></key>
<data><![CDATA[ 基于Model的Spider,封装后的入口类。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-3 <br>
Time: 上午9:51 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.OOSpider(us.codecraft.webmagic.Site, us.codecraft.webmagic.pipeline.PageModelPipeline, java.lang.Class...)]]></key>
<data><![CDATA[ 创建一个爬虫。<br>
@param site
@param pageModelPipeline
@param pageModels
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.PageModelPipeline]]></key>
<data><![CDATA[ @author code4crafter@gmail.com <br>
Date: 13-8-3 <br>
Time: 上午9:34 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ComboExtract]]></key>
<data><![CDATA[ @author code4crafter@gmail.com <br>
Date: 13-8-16 <br>
Time: 下午11:09 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractBy]]></key>
<data><![CDATA[ 定义类或者字段的抽取规则。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-1 <br>
Time: 下午8:40 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractBy.value]]></key>
<data><![CDATA[ 抽取规则
@return 抽取规则
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractBy.type]]></key>
<data><![CDATA[ 抽取规则类型,支持XPath、Css selector、正则表达式,默认是XPath
@return 抽取规则类型
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractBy.notNull]]></key>
<data><![CDATA[ 是否是不能为空的关键字段,若notNull为true,则对应字段抽取不到时,丢弃整个类,默认为false
@return 是否是不能为空的关键字段
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractBy.multi]]></key>
<data><![CDATA[ 是否抽取多个结果<br>
用于字段时,需要List<String>来盛放结果<br>
用于类时,表示单页抽取多个对象<br>
@return 是否抽取多个结果
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractBy2]]></key>
<data><![CDATA[ 定义类或者字段的抽取规则,只能在Extract、ExtractByRaw之后使用。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-1 <br>
Time: 下午8:40 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractBy3]]></key>
<data><![CDATA[ 定义类或者字段的抽取规则,只能在Extract、ExtractByRaw之后使用。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-1 <br>
Time: 下午8:40 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByRaw]]></key>
<data><![CDATA[ 对于在Class级别就使用过ExtractBy的类,在字段中想抽取全部内容可使用此方法。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-1 <br>
Time: 下午8:40 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByRaw.value]]></key>
<data><![CDATA[ 抽取规则
@return 抽取规则
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByRaw.type]]></key>
<data><![CDATA[ 抽取规则类型,支持XPath、Css selector、正则表达式,默认是XPath
@return 抽取规则类型
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByRaw.notNull]]></key>
<data><![CDATA[ 是否是不能为空的关键字段,若notNull为true,则对应字段抽取不到时,丢弃整个类,默认为false
@return 是否是不能为空的关键字段
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByRaw.multi]]></key>
<data><![CDATA[ 是否抽取多个结果<br>
需要List<String>来盛放结果<br>
@return 是否抽取多个结果
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByUrl]]></key>
<data><![CDATA[ 定义类或者字段的抽取规则(从url中抽取,只支持正则表达式)。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-1 <br>
Time: 下午8:40 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByUrl.value]]></key>
<data><![CDATA[ 抽取规则,支持正则表达式
@return 抽取规则
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByUrl.notNull]]></key>
<data><![CDATA[ 是否是不能为空的关键字段,若notNull为true,则对应字段抽取不到时,丢弃整个类,默认为false
@return 是否是不能为空的关键字段
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.ExtractByUrl.multi]]></key>
<data><![CDATA[ 是否抽取多个结果<br>
用于字段时,需要List<String>来盛放结果<br>
用于类时,表示单页抽取多个对象<br>
@return 是否抽取多个结果
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.HelpUrl]]></key>
<data><![CDATA[ 定义辅助爬取的url。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-1 <br>
Time: 下午8:40 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.HelpUrl.value]]></key>
<data><![CDATA[ 某个类对应的URL规则列表<br>
webmagic对正则表达式进行了修改,"."仅表示字符"."而不代表任意字符,而"\*"则代表了".\*",例如"http://\*.oschina.net/\*"代表了oschina所有的二级域名下的URL。<br>
@return 抽取规则
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.HelpUrl.sourceRegion]]></key>
<data><![CDATA[ 指定提取URL的区域(仅支持XPath)
@return 指定提取URL的区域
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.TargetUrl]]></key>
<data><![CDATA[ 定义某个类抽取的范围和来源,sourceRegion可以用xpath语法限定抽取区域。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-1 <br>
Time: 下午8:40 <br>
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.TargetUrl.value]]></key>
<data><![CDATA[ 某个类对应的URL规则列表<br>
webmagic对正则表达式进行了修改,"."仅表示字符"."而不代表任意字符,而"\*"则代表了".\*",例如"http://\*.oschina.net/\*"代表了oschina所有的二级域名下的URL。<br>
@return 抽取规则
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation.TargetUrl.sourceRegion]]></key>
<data><![CDATA[ 指定提取URL的区域(仅支持XPath)
@return 指定提取URL的区域
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model.annotation]]></key>
<data><![CDATA[
webmagic注解抓取方式所定义的注解。
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.model]]></key>
<data><![CDATA[
webmagic对抓取器编写的面向模型(称为PageModel)的封装。基于POJO及注解即可实现一个PageProcessor。
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic]]></key>
<data><![CDATA[
<div class="en">
Main class "Spider" and models.
</div>
<div class="zh">
包括webmagic入口类Spider和一些数据传递的实体类。
</div>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.ConsolePipeline]]></key>
<data><![CDATA[ 命令行输出抽取结果。可用于测试。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午1:45
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.FilePipeline]]></key>
<data><![CDATA[ 持久化到文件的接口。
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午6:28
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.FilePipeline()]]></key>
<data><![CDATA[ 新建一个FilePipeline,使用默认保存路径"/data/webmagic/"
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.FilePipeline(java.lang.String)]]></key>
<data><![CDATA[ 新建一个FilePipeline
@param path 文件保存路径
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.JsonFilePageModelPipeline]]></key>
<data><![CDATA[ JSON格式持久化到文件的接口。<br>
如果持久化的文件名是乱码,请再运行的环境变量里加上LANG=zh_CN.UTF-8。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午6:28
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.JsonFilePageModelPipeline()]]></key>
<data><![CDATA[ 新建一个JsonFilePageModelPipeline,使用默认保存路径"/data/webmagic/"
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.JsonFilePageModelPipeline(java.lang.String)]]></key>
<data><![CDATA[ 新建一个JsonFilePageModelPipeline
@param path 文件保存路径
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.JsonFilePipeline]]></key>
<data><![CDATA[ JSON格式持久化到文件的接口。
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午6:28
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.JsonFilePipeline()]]></key>
<data><![CDATA[ 新建一个JsonFilePipeline,使用默认保存路径"/data/webmagic/"
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.JsonFilePipeline(java.lang.String)]]></key>
<data><![CDATA[ 新建一个JsonFilePipeline
@param path 文件保存路径
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.MultiPagePipeline]]></key>
<data><![CDATA[ 用于实现分页的Pipeline。<br>
在使用redis做分布式爬虫时,请不要使用此功能。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-4 <br>
Time: 下午5:15 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline.Pipeline]]></key>
<data><![CDATA[ Pipeline是数据离线处理和持久化的接口。通过实现Pipeline以实现不同的持久化方式(例如保存到数据库)。
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午1:39
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.pipeline]]></key>
<data><![CDATA[
包含了处理页面抽取结果的接口Pipeline和它的几个实现类。
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.processor.PageProcessor]]></key>
<data><![CDATA[ 定制爬虫的核心接口。通过实现PageProcessor可以实现一个定制的爬虫。<br>
extends the class to implements various spiders.<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午11:42
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.processor.PageProcessor.process(us.codecraft.webmagic.Page)]]></key>
<data><![CDATA[ 定义如何处理页面,包括链接提取、内容抽取等。
@param page
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.processor.PageProcessor.getSite()]]></key>
<data><![CDATA[ 定义任务一些配置信息,例如开始链接、抓取间隔、自定义cookie、自定义UA等。
@return site
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.processor.SimplePageProcessor]]></key>
<data><![CDATA[ 非常简单的抽取器。链接抽取使用定义的通配符,并保存抽取整个内容到content字段。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-22
Time: 下午9:15
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.processor]]></key>
<data><![CDATA[
包含了封装页面处理逻辑的接口PageProcessor和一个实现类SimplePageProcessor。实现PageProcessor即可定制一个自己的爬虫。
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.scheduler.FileCacheQueueScheduler]]></key>
<data><![CDATA[ 磁盘文件实现的url管理模块,可以保证在长时间执行的任务中断后,下次启动从中断位置重新开始。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午1:13
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.scheduler.QueueScheduler]]></key>
<data><![CDATA[ 内存队列实现的线程安全Scheduler。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午1:13
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.scheduler.RedisScheduler]]></key>
<data><![CDATA[ 使用redis管理url,构建一个分布式的爬虫。<br>
@author code4crafter@gmail.com <br>
Date: 13-7-25 <br>
Time: 上午7:07 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.scheduler.Scheduler]]></key>
<data><![CDATA[ 包含url管理和调度的接口。包括url抓取队列,url去重等功能。<br>
Scheduler的接口包含一个Task参数,该参数是为单Scheduler多Task预留的(Spider就是一个Task)。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午1:12
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.scheduler.Scheduler.push(us.codecraft.webmagic.Request, us.codecraft.webmagic.Task)]]></key>
<data><![CDATA[ 加入一个待抓取的链接
@param request 待抓取的链接
@param task 定义的任务,以满足单Scheduler多Task的情况
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.scheduler.Scheduler.poll(us.codecraft.webmagic.Task)]]></key>
<data><![CDATA[ 返回下一个要抓取的链接
@param task 定义的任务,以满足单Scheduler多Task的情况
@return 下一个要抓取的链接
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.scheduler]]></key>
<data><![CDATA[
包含url管理和调度的接口Scheduler及它的几个实现类。
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.AndSelector]]></key>
<data><![CDATA[ @author code4crafter@gmail.com <br>
Date: 13-8-3 <br>
Time: 下午5:29 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.CssSelector]]></key>
<data><![CDATA[ css风格的选择器。包装了Jsoup。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午9:39
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Html]]></key>
<data><![CDATA[ 可抽取的html文本。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午7:54
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.JsonPathSelector]]></key>
<data><![CDATA[ @author code4crafter@gmail.com <br>
Date: 13-8-12 <br>
Time: 下午12:54 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.OrSelector]]></key>
<data><![CDATA[ @author code4crafter@gmail.com <br>
Date: 13-8-3 <br>
Time: 下午5:29 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.PlainText]]></key>
<data><![CDATA[ 可抽取的纯文本,不包括xpath和css selector实现。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午7:54
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.RegexSelector]]></key>
<data><![CDATA[ 正则表达式抽取器。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午7:09
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.ReplaceSelector]]></key>
<data><![CDATA[ 对文本进行替换。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午7:09
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable]]></key>
<data><![CDATA[ 可进行抽取的文本。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-20
Time: 下午7:51
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.xpath(java.lang.String)]]></key>
<data><![CDATA[ select list with xpath
@param xpath
@return new Selectable after extract
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.$(java.lang.String)]]></key>
<data><![CDATA[ select list with css selector
@param selector css selector expression
@return new Selectable after extract
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.smartContent()]]></key>
<data><![CDATA[ select smart content with ReadAbility algorithm
@return content
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.links()]]></key>
<data><![CDATA[ select all links
@return all links
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.regex(java.lang.String)]]></key>
<data><![CDATA[ select list with regex
@param regex
@return new Selectable after extract
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.replace(java.lang.String, java.lang.String)]]></key>
<data><![CDATA[ replace with regex
@param regex
@param replacement
@return new Selectable after extract
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.toString()]]></key>
<data><![CDATA[ single string result
@return single string result
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selectable.all()]]></key>
<data><![CDATA[ multi string result
@return multi string result
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.Selector]]></key>
<data><![CDATA[ 抽取器。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-20
Time: 下午8:02
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.SelectorFactory]]></key>
<data><![CDATA[ 产生selector的工厂。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午7:56
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.SmartContentSelector]]></key>
<data><![CDATA[ readability算法,基础是找到所有p标签的父节点
写的比较乱,最终效果还在尝试中
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午4:42
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector.XpathSelector]]></key>
<data><![CDATA[ xpath的选择器。包装了HtmlCleaner。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 上午9:39
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.selector]]></key>
<data><![CDATA[
提供了便捷抽取页面内容的工具,对外核心接口是Selectable,内部抽取则是通过实现Selector来定制。
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap]]></key>
<data><![CDATA[ @author code4crafter@gmail.com
Date Dec 14, 2012
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap(java.util.Map<K1, java.util.Map<K2, V>>, java.lang.Class<? extends java.util.Map>)]]></key>
<data><![CDATA[ init map with protoMapClass
@param protoMapClass
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap.get(K1)]]></key>
<data><![CDATA[ @param key
@return map
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap.get(K1, K2)]]></key>
<data><![CDATA[ @param key1
@param key2
@return value
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap.put(K1, java.util.Map<K2, V>)]]></key>
<data><![CDATA[ @param key1
@param submap
@return
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap.put(K1, K2, V)]]></key>
<data><![CDATA[ @param key1
@param key2
@param value
@return
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap.remove(K1, K2)]]></key>
<data><![CDATA[ @param key1
@param key2
@return
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.DoubleKeyMap.remove(K1)]]></key>
<data><![CDATA[ @param key1
@return
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.FilePersistentBase]]></key>
<data><![CDATA[ 文件持久化的基础类。<br>
@author code4crafter@gmail.com <br>
Date: 13-8-11 <br>
Time: 下午4:21 <br>
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.MultiKeyMapBase]]></key>
<data><![CDATA[ multikey map, some basic objects *
@author yihua.huang
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.ThreadUtils]]></key>
<data><![CDATA[ 线程工具类。<br>
@author code4crafer@gmail.com
Date: 13-6-23
Time: 下午7:11
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:46 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.UrlUtils]]></key>
<data><![CDATA[ url及html处理工具类。<br>
@author code4crafter@gmail.com <br>
Date: 13-4-21
Time: 下午1:52
]]></data>
</comment>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils.UrlUtils.canonicalizeUrl(java.lang.String, java.lang.String)]]></key>
<data><![CDATA[ 将url想对地址转化为绝对地址
@param url url地址
@param refer url地址来自哪个页面
@return url绝对地址
]]></data>
</comment>
</javadoc>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<javadoc>
<meta>
<date-generated>Sat Aug 17 14:14:45 CST 2013</date-generated>
</meta>
<comment>
<key><![CDATA[us.codecraft.webmagic.utils]]></key>
<data><![CDATA[
提供一些处理链接的静态工具类。
]]></data>
</comment>
</javadoc>
WebMagic in Action
========
WebMagic是一个简单灵活、便于二次开发的爬虫框架。除了可以便捷的实现一个爬虫,WebMagic还提供多线程功能,以及基本的分布式功能。
你可以直接使用WebMagic进行爬虫开发,也可以定制WebMagic以适应复杂项目的需要。
## 1. 在项目中使用WebMagic
WebMagic主要包含两个jar包:`webmagic-core-{version}.jar``webmagic-extension-{version}.jar`。在项目中添加这两个包的依赖,即可使用WebMagic。
### 1.1 使用Maven
WebMagic基于Maven进行构建,推荐使用Maven来安装WebMagic。在项目中添加以下坐标即可:
```xml
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.4.3</version>
</dependency>
```
WebMagic使用slf4j-log4j12作为slf4j的实现.如果你自己定制了slf4j的实现,请在项目中去掉此依赖。
```xml
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.4.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
```
### 1.2 不使用Maven
不使用maven的用户,可以下载附带二进制jar包的版本(感谢[oschina](http://www.oschina.net/)):
git clone http://git.oschina.net/flashsword20/webmagic.git
**lib**目录下,有项目依赖的所有jar包,直接在IDE里,将这些jar添加到Libraries即可。
![import jars](http://static.oschina.net/uploads/space/2014/0403/143318_gBQE_190591.jpeg)
### 1.3 第一个项目
在你的项目中添加了WebMagic的依赖之后,即可开始第一个爬虫的开发了!我们这里拿一个抓取Github信息的例子:
```java
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
public class GithubRepoPageProcessor implements PageProcessor {
private Site site = Site.me().setRetryTimes(3).setSleepTime(100);
@Override
public void process(Page page) {
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());
page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString());
page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString());
if (page.getResultItems().get("name")==null){
//skip this page
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();
}
}
```
点击main方法,选择“运行”,你会发现爬虫已经可以正常工作了!
![runlog](http://static.oschina.net/uploads/space/2014/0403/103741_3Gf5_190591.png)
<div style="page-break-after:always"></div>
## 2.下载和编译源码
WebMagic是一个纯Java项目,如果你熟悉Maven,那么下载并编译源码是非常简单的。如果不熟悉Maven也没关系,这部分会介绍如何在Eclipse里导入这个项目。
### 2.1 下载源码
WebMagic目前有两个仓库:
* [https://github.com/code4craft/webmagic](https://github.com/code4craft/webmagic)
github上的仓库保存最新版本,所有issue、pull request都在这里。大家觉得项目不错的话别忘了去给个star哦!
* [http://git.oschina.net/flashsword20/webmagic](http://git.oschina.net/flashsword20/webmagic)
此仓库包含所有编译好的依赖包,只保存项目的稳定版本,最新版本仍在github上更新。oschina在国内比较稳定,主要作为镜像。
无论在哪个仓库,使用
git clone https://github.com/code4craft/webmagic.git
或者
git clone http://git.oschina.net/flashsword20/webmagic.git
即可下载最新代码。
如果你对git本身使用也不熟悉,建议看看@黄勇的 [从 Git@OSC 下载 Smart 源码](http://my.oschina.net/huangyong/blog/200075)
### 2.2 导入项目
Intellij Idea默认自带Maven支持,import项目时选择Maven项目即可。
#### 2.2.1 使用m2e插件
使用Eclipse的用户,推荐安装m2e插件,安装地址:https://www.eclipse.org/m2e/download/[](https://www.eclipse.org/m2e/download/)
安装后,在File->Import中选择Maven->Existing Maven Projects即可导入项目。
![m2e-import](http://static.oschina.net/uploads/space/2014/0403/104427_eNuc_190591.png)
导入后看到项目选择界面,点击finish即可。
![m2e-import2](http://static.oschina.net/uploads/space/2014/0403/104735_6vwG_190591.png)
#### 2.2.2 使用Maven Eclipse插件
如果没有安装m2e插件,只要你安装了Maven,也是比较好办的。在项目根目录下使用命令:
mvn eclipse:eclipse
生成maven项目结构的eclipse配置文件,然后在File->Import中选择General->Existing Projects into Workspace即可导入项目。
![eclipse-import-1](http://static.oschina.net/uploads/space/2014/0403/100025_DAcy_190591.png)
导入后看到项目选择界面,点击finish即可。
![eclipse-import-2](http://static.oschina.net/uploads/space/2014/0403/100227_73DJ_190591.png)
### 2.3 编译和执行源码
导入成功之后,应该就没有编译错误了!此时你可以运行一下webmagic-core项目中自带的exmaple:"us.codecraft.webmagic.processor.example.GithubRepoPageProcessor"。
同样,看到控制台输出如下,则表示源码编译和执行成功了!
![runlog](http://static.oschina.net/uploads/space/2014/0403/103741_3Gf5_190591.png)
<div style="page-break-after:always"></div>
## 3. 基本的爬虫
### 3.1 实现PageProcessor
在WebMagic里,实现一个基本的爬虫只需要编写一个类,实现`PageProcessor`接口即可。这个类基本上包含了抓取一个网站,你需要写的所有代码。
以之前的`GithubRepoPageProcessor`为例,我将PageProcessor的定制分为三个部分,分别是爬虫的配置、页面元素的抽取和链接的发现。
```java
public class GithubRepoPageProcessor implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);
@Override
// process是定制爬虫逻辑的核心接口,在这里编写抽取逻辑
public void process(Page page) {
// 部分二:定义如何抽取页面信息,并保存下来
page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString());
page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString());
if (page.getResultItems().get("name") == null) {
//skip this page
page.setSkip(true);
}
page.putField("readme", page.getHtml().xpath("//div[@id='readme']/tidyText()"));
// 部分三:从页面发现后续的url地址来抓取
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) {
Spider.create(new GithubRepoPageProcessor())
//从"https://github.com/code4craft"开始抓
.addUrl("https://github.com/code4craft")
//开启5个线程抓取
.thread(5)
//启动爬虫
.run();
}
}
```
#### 3.1.1 爬虫的配置
第一部分关于爬虫的配置,包括编码、抓取间隔、超时时间、重试次数等,也包括一些模拟的参数,例如User Agent、cookie,以及代理的设置,我们会在第5章-“爬虫的配置”里进行介绍。在这里我们先简单设置一下:重试次数为3次,抓取间隔为一秒。
#### 3.1.2 页面元素的抽取
第二部分是爬虫的核心部分:对于下载到的Html页面,你如何从中抽取到你想要的信息?WebMagic里主要使用了三种抽取技术:XPath、正则表达式和CSS选择器。
1. XPath
XPath本来是用于XML中获取元素的一种查询语言,但是用于Html也是比较方便的。例如:
```java
page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()")
```
这段代码使用了XPath,它的意思是“查找所有class属性为'entry-title public'的h1元素,并找到他的strong子节点的a子节点,并提取a节点的文本信息”。
对应的Html是这样子的:
![xpath-html](http://static.oschina.net/uploads/space/2014/0404/104607_Aqq8_190591.png)
2. CSS选择器
CSS选择器是与XPath类似的语言。如果大家做过前端开发,肯定知道$('h1.entry-title')这种写法的含义。客观的说,它比XPath写起来要简单一些,但是如果写复杂一点的抽取规则,就相对要麻烦一点。
3. 正则表达式
正则表达式则是一种通用的文本抽取语言。
```java
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());
```
这段代码就用到了正则表达式,它表示匹配所有"https://github.com/code4craft/webmagic"这样的链接。
XPath、CSS选择器和正则表达式的具体用法会在第4章“抽取工具详解”中讲到。
#### 3.1.3 链接的发现
有了处理页面的逻辑,我们的爬虫就接近完工了!
但是现在还有一个问题:一个站点的页面是很多的,一开始我们不可能全部列举出来,于是如何发现后续的链接,是一个爬虫不可缺少的一部分。
```java
page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());
```
这段代码的分为两部分,`page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all()`用于获取所有满足"(https://github\\.com/\\w+/\\w+)"这个正则表达式的链接,`page.addTargetRequests()`则将这些链接加入到待抓取的队列中去。
### 3.2 使用Selectable的链式API
`Selectable`相关的链式API是WebMagic的一个核心功能。使用Selectable接口,你可以直接完成页面元素的链式抽取,也无需去关心抽取的细节。
在刚才的例子中可以看到,page.getHtml()返回的是一个`Html`对象,它实现了`Selectable`接口。这个接口包含一些重要的方法,我将它分为两类:抽取部分和获取结果部分。
#### 3.2.1 抽取部分API:
| 方法 | 说明 | 示例 |
| ------------ | ------------- | ------------ |
| xpath(String xpath) | 使用XPath选择 | html.xpath("//div[@class='title']") |
| \$(String selector) | 使用Css选择器选择 | html.\$("div.title") |
| \$(String selector,String attr) | 使用Css选择器选择 | html.\$("div.title","text") |
| css(String selector) | 功能同$(),使用Css选择器选择 | html.css("div.title") |
| links() | 选择所有链接 | html.links() |
| regex(String regex) | 使用正则表达式抽取 | html.regex("\<div\>(.\*?)\</div>") |
| regex(String regex,int group) | 使用正则表达式抽取,并指定捕获组 | html.regex("\<div\>(.\*?)\</div>",1) |
| replace(String regex, String replacement) | 替换内容| html.replace("\<script>.\*\</script>","")|
这部分抽取API返回的都是一个`Selectable`接口,意思是说,抽取是支持链式调用的。下面我用一个实例来讲解链式API的使用。
例如,我现在要抓取github上所有的Java项目,这些项目可以在[https://github.com/search?l=Java&p=1&q=stars%3A%3E1&s=stars&type=Repositories](https://github.com/search?l=Java&p=1&q=stars%3A%3E1&s=stars&type=Repositories)搜索结果中看到。
为了避免抓取范围太宽,我指定只从分页部分抓取链接。这个抓取规则是比较复杂的,我会要怎么写呢?
![selectable-chain-ui](http://static.oschina.net/uploads/space/2014/0404/151454_2T01_190591.png)
首先看到页面的html结构是这个样子的:
![selectable-chain](http://static.oschina.net/uploads/space/2014/0404/151632_88Oq_190591.png)
那么我可以先用CSS选择器提取出这个div,然后在取到所有的链接。为了保险起见,我再使用正则表达式限定一下提取出的URL的格式,那么最终的写法是这样子的:
```java
List<String> urls = page.getHtml().css("div.pagination").links().regex(".*/search/\?l=java.*").all();
```
然后,我们可以把这些URL加到抓取列表中去:
```java
List<String> urls = page.getHtml().css("div.pagination").links().regex(".*/search/\?l=java.*").all();
page.addTargetRequests(urls);
```
是不是比较简单?除了发现链接,Selectable的链式抽取还可以完成很多工作。我们会在第9章示例中再讲到。
#### 3.2.2 获取结果的API:
当链式调用结束时,我们一般都想要拿到一个字符串类型的结果。这时候就需要用到获取结果的API了。我们知道,一条抽取规则,无论是XPath、CSS选择器或者正则表达式,总有可能抽取到多条元素。WebMagic对这些进行了统一,你可以通过不同的API获取到一个或者多个元素。
| 方法 | 说明 | 示例 |
| ------------ | ------------- | ------------ |
| get() | 返回一条String类型的结果 | String link= html.links().get()|
| toString() | 功能同get(),返回一条String类型的结果 | String link= html.links().toString()|
| all() | 返回所有抽取结果 | List<String> links= html.links().all()|
| match() | 是否有匹配结果 | if (html.links().match()){ xxx; }|
例如,我们知道页面只会有一条结果,那么可以使用selectable.get()或者selectable.toString()拿到这条结果。
这里selectable.toString()采用了toString()这个接口,是为了在输出以及和一些框架结合的时候,更加方便。因为一般情况下,我们都只需要选择一个元素!
selectable.all()则会获取到所有元素。
好了,到现在为止,在回过头看看3.1中的GithubRepoPageProcessor,可能就觉得更加清晰了吧?指定main方法,已经可以看到抓取结果在控制台输出了。
### 3.3 保存结果
好了,爬虫编写完成,现在我们可能还有一个问题:我如果想把抓取的结果保存下来,要怎么做呢?WebMagic用于保存结果的组件叫做`Pipeline`。例如我们通过“控制台输出结果”这件事也是通过一个内置的Pipeline完成的,它叫做`ConsolePipeline`。那么,我现在想要把结果用Json的格式保存下来,怎么做呢?我只需要将Pipeline的实现换成"JsonFilePipeline"就可以了。
```java
public static void main(String[] args) {
Spider.create(new GithubRepoPageProcessor())
//从"https://github.com/code4craft"开始抓
.addUrl("https://github.com/code4craft")
.addPipeline(new JsonFilePipeline("D:\webmagic\"))
//开启5个线程抓取
.thread(5)
//启动爬虫
.run();
}
```
这样子下载下来的文件就会保存在D盘的webmagic目录中了。
通过定制Pipeline,我们还可以实现保存结果到文件、数据库等一系列功能。这个会在第7章“抽取结果的处理”中介绍。
至此为止,我们已经完成了一个基本爬虫的编写,也具有了一些定制功能。
<div style="page-break-after:always"></div>
## 4. 抽取工具详解
### 4.1 XPath
### 4.2 CSS选择器
### 4.3 正则表达式
### 4.4 JsonPath
## 5. 配置爬虫
### 5.1 抓取频率
### 5.2 编码
### 5.3 代理
### 5.4 设置cookie/UA等http头信息
### 5.5 重试机制
### 5.6 多线程
## 6. 爬虫的启动和终止
### 6.1 启动爬虫
### 6.2 终止爬虫
### 6.3 设置执行时间
### 6.4 定期抓取
## 7. 抽取结果的处理
### 7.1 输出到控制台
### 7.2 保存到文件
### 7.3 JSON格式输出
### 7.4 自定义持久化方式(mysql/mongodb…)
## 8. 管理URL
### 8.1 手动添加URL
### 8.2 在URL中保存信息
### 8.3 几种URL管理方式
### 8.4 自己管理爬虫的URL
## 9. 实例
### 9.1 基本的列表+详情页的抓取
### 9.2 抓取动态页面
### 9.3 分页抓取
### 9.4 定期抓取
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment