You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Go to file
yihua.huang d1fc1cf305 add diaoyuwen 12 years ago
src add diaoyuwen 12 years ago
.gitignore init 12 years ago
README.md readme 12 years ago
pom.xml init 12 years ago

README.md

webmagic

####一个网络爬虫工具包

webmagic的发起源于工作中的需要其定位是帮助开发者更便捷的开发一个垂直的网络爬虫。webmagic可以便捷的使用xpath和正则表达式进行链接和内容的提取对于有Java和xpath或者正则基础的开发者只需编写少量代码即可完成一个定制爬虫。

###哲学###

  • Write Less, Do more.

    webmagic是一个开发者的工具包它的目标是让开发者可以通过更少的代码实现一个高质量的爬虫。webmagic内部还集成了一些常见的垂直性爬虫的功能例如针对页面正文的Readability技术可以直接对页面的正文进行智能提取。

    以下是爬取oschina博客的一段代码

      Spider.me().processor(new SimplePageProcessor("http://my.oschina.net/", "http://my.oschina.net/*/blog/*")).run();
    
  • 简单可用

    webmagic的功能覆盖整个爬虫的生命周期(链接提取、页面下载、内容抽取、持久化)是一个完整的爬虫框架。但是与其他Full-Stack的框架不同webmagic只引入少量约定大部分功能都通过简单的API调用完成目的是尽量降低开发者的学习成本。webmagic以jar包的形式存在并且不依赖任何框架在程序可以随处进行调用。

  • 灵活性

    参考scrapy的设计webmagic将爬虫的扩展点分为processor、schedular、downloader、pipeline三个模块可以通过扩展这些接口实现强大的扩展功能。如可以通过多个Spider实现多线程抓取可以通过扩展schedular实现断点续传乃至于分布式爬虫可以通过扩展pipeline实现业务可定制的持久化功能。


###Get Started

webmagic定制的核心是PageProcessor接口。一个最简单的webmagic爬虫例子是这样的

Spider.me().processor(new SimplePageProcessor("http://my.oschina.net/", "http://my.oschina.net/*/blog/*")).run();

其中SimplePageProcessor实现如下

public class SimplePageProcessor implements PageProcessor {

    private String urlPattern;

    private static final String UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31";

    private Site site;

    public SimplePageProcessor(String startUrl, String urlPattern) {
        this.site = Site.me().setStartUrl(startUrl).
                setDomain(UrlUtils.getDomain(startUrl)).setUserAgent(UA);
        this.urlPattern = "("+urlPattern.replace(".","\\.").replace("*","[^\"'#]*")+")";

    }

    @Override
    public void process(Page page) {
        List<String> requests = page.getHtml().as().rs(urlPattern).toStrings();
        page.addTargetRequests(requests);
        page.putField("title", page.getHtml().x("//title"));
        page.putField("content", page.getHtml().sc());
    }

    @Override
    public Site getSite() {
        return site;
    }
}

TODO

	public class OschinaBlogPageProcesser implements PageProcessor {

    @Override
    public void process(Page page) {
        List<String> strings = page.getHtml().rs("<a[^<>]*href=[\"']{1}(http://my\\.oschina\\.net/\\w+/blog/\\d+)[\"']{1}").toStrings();
        page.addTargetRequests(strings);
        page.putField("title", page.getHtml().xs("//div[@class='BlogEntity']/div[@class='BlogTitle']/h1"));
        page.putField("content", page.getHtml().sc());
        page.putField("author", page.getUrl().r("my\\.oschina\\.net/(\\w+)/blog/\\d+"));
    }

    @Override
    public Site getSite() {
        return Site.me().setDomain("my.oschina.net").setStartUrl("http://www.oschina.net/").
                setUserAgent("Mozilla/5.0 (Macintosh; Chrome/26.0.1410.65 Safari/537.31");
    	}
	}