一、采集大数据的方法
1.1通过系统日志采集大数据
用于系统日志采集的工具,目前使用最广泛的有:Hadoop 的Chukwa、ApacheFlumeAFacebook的Scribe和LinkedIn的Kafka等。这里主要学习Flume。
Flume是一个高可靠的分布式采集、聚合和传输系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据,同时对数据进行简单处理,并写到诸如文本、HDFS这些接受方中。
Flume的核心其实就是把数据从数据源收集过来,再将收集到的数据送到指定的目的地……
1.2通过网络采集大数据
网络采集是指通过网络爬虫或网站公开API等方式,从网站上获取大数据信息,该方法可以将非结构化数据从网页中抽取出来,将其存储为统一的本地数据文件,并以结构化的方式存储。它支持图片、音频、视频等文件或附件的采集。
一般来说,网络爬虫工具基本可以分类3类:分布式网络爬虫工具(Nutch)、Java网络爬虫工具(Crawler4j、WebMagic、WebCollector)、非Java网络爬虫工具( Scrapy)。
1.2.1网络爬虫原理
所谓的网络爬虫,其实是一种按照一定规则,自动地抓取web信息的程序或脚本。
网络爬虫可以自动采集所有其能够访问到的页面内容,为搜索引擎和大数据分析提供数据来源,一般有数据采集、数据处理和数据存储三部分功能。
网络爬虫是如何爬数据的? 这是因为网页中除了供用户浏览的文字信息外,还包含一些超链接信息,通过获取这些超链接URL,再辅以一定的算法,爬虫就能得到数据了。
1.2.2爬虫工作流程
基本情况下,爬虫会首先获取一部分种子URL,将这些URL放入待抓取URL队列,从队列中取出待抓取URL,解析DNS得到主机IP,并将URL对应网页下载储存。最后将这些URL放入已抓取队列中,如此循环。
1.2.3爬虫抓取策略
互联网上的网页数量以亿级为单位,该以什么样的策略爬这些网页的数据成为了一个问题,大致分为几个类型。
通用网络爬虫,又称为全网爬虫,主要为门户站点搜索引擎和大型web服务提供商采集数据,又分为深度优先策略和广度优先策略。 聚焦网络爬虫,又称为主题网络爬虫,是指选择性地爬行那些与预先定义好的主题相关的页面的网络爬虫。也就是有一个明显的主题,比如文本、比如图片……聚焦网络爬虫又分为几种:1.基于内容、2.基于链接结构、3.基于增强学习(?)、4.基于语境(?) 增量式网络爬虫,是指获取的目标网页尽量为新网页。 深层网络爬虫,如果将那些传统搜索引擎可以索引的页面归属于表层网页,那么深层网络爬虫获取的页面就是之外的“深层网页”。1.3具体的爬虫工具
1.3.1Scrapy
Scrapy 是一个为了爬取网站数据、提取结构性数据而编写的应用框架,可以应用在包括数据挖掘、信息处理或存储历史数据等一系列的程序中。
虽然Scrpay非常强大,不过它是适用于Python的,而本人正好又没有接触过Python,所以这一部分暂且只做了解……
1.3.2Crawler4j、WebMagic、WebCollector
这三者都是JAVA的单机爬虫开源框架,区别可能是在于算法和调度之类的地方?这点搜索了一下,都没有能查到,就姑且这样认为吧。
这里我就用WebMagic做一个Demo试一试吧!
1.4跑一下WebMagic
百度后我找到了WebMagic的官方文档
照着里面的例子测试一下:
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();
}
}
运行走一波,发现报错了……
log4j:WARN No appenders could be found for logger (us.codecraft.webmagic.scheduler.QueueScheduler).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
一看就是log4j的问题,尝试添加配置文件log4j.properties,再次运行,嗯?居然还是报错了……
好吧,看一看官方文档,原来作者说了:
WebMagic使用slf4j-log4j12作为slf4j的实现.如果你自己定制了slf4j的实现,请在项目中去掉此依赖。
ok,让我来替换成普通的log4j依赖:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
果不其然,这几部操作之后就能正常运行了,点击run跑起来!竟然又有了新的问题……
[us.codecraft.webmagic.Spider] - Spider github.com started!
[us.codecraft.webmagic.downloader.HttpClientDownloader] - download page https://github.com/code4craft error
难道是网络的“不可抗力的问题”,所以才失败了?
继续寻找原因最后在官方文档上找到了另外一个demo,尝试使用:
public class SinaBlogProcessor implements PageProcessor {
public static final String URL_LIST = "http://blog\\.sina\\.com\\.cn/s/articlelist_1487828712_0_\\d+\\.html";
public static final String URL_POST = "http://blog\\.sina\\.com\\.cn/s/blog_\\w+\\.html";
private Site site = Site
.me()
.setDomain("blog.sina.com.cn")
.setSleepTime(3000)
.setUserAgent(
"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");
@Override
public void process(Page page) {
//列表页
if (page.getUrl().regex(URL_LIST).match()) {
page.addTargetRequests(page.getHtml().xpath("//div[@class=\"articleList\"]").links().regex(URL_POST).all());
page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());
//文章页
} else {
page.putField("title", page.getHtml().xpath("//div[@class='articalTitle']/h2"));
page.putField("content", page.getHtml().xpath("//div[@id='articlebody']//div[@class='articalContent']"));
page.putField("date",
page.getHtml().xpath("//div[@id='articlebody']//span[@class='time SG_txtc']").regex("\\((.*)\\)"));
}
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) {
Spider.create(new SinaBlogProcessor()).addUrl("http://blog.sina.com.cn/s/articlelist_1487828712_0_1.html")
.run();
}
}
嗯,这个demo爬的是博客的数据,没有了“不可抗力的问题”,果然这回就成功了。
总结
数据的采集大概就是通过系统日志获取和通过爬虫获取这两种,虽然试验了爬虫中的WebMagic方式,不过也只是简单的跑起来而已,中间想要修改代码达成自己想要的结果,不过因为时间问题,而且其中用到的正则表达式我并没有系统学过,所以也只能遗憾收手,将这个念想留到以后再继续实现。
参考
WebMagic官方文档
C语言中文网