大数据中数据采集的几种方式

2022-08-31 10:18:48 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

一、采集大数据的方法

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的官方文档

照着里面的例子测试一下:

  • 首先新建一个maven项目,是不是web项目都可以,只要是maven就行了。嗯,当然不要maven也可以手动导入jar包,不过为了方便还是使用maven吧。
  • 官网有一个官方的简单例子
代码语言:javascript复制
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();
    }
}

运行走一波,发现报错了……

代码语言:javascript复制
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,再次运行,嗯?居然还是报错了……

好吧,看一看官方文档,原来作者说了:

代码语言:javascript复制
WebMagic使用slf4j-log4j12作为slf4j的实现.如果你自己定制了slf4j的实现,请在项目中去掉此依赖。

ok,让我来替换成普通的log4j依赖:

代码语言:javascript复制
<dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.25</version>
    </dependency>

果不其然,这几部操作之后就能正常运行了,点击run跑起来!竟然又有了新的问题……

代码语言:javascript复制
[us.codecraft.webmagic.Spider] - Spider github.com started!
[us.codecraft.webmagic.downloader.HttpClientDownloader] - download page https://github.com/code4craft error

难道是网络的“不可抗力的问题”,所以才失败了?

  • 继续寻找原因 最后在官方文档上找到了另外一个demo,尝试使用:
代码语言:javascript复制
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语言中文网

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/143866.html原文链接:https://javaforall.cn

0 人点赞