Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用ApacheSpark进行分布式Web爬行-可能吗?_Web_Apache Spark_Web Crawler - Fatal编程技术网

使用ApacheSpark进行分布式Web爬行-可能吗?

使用ApacheSpark进行分布式Web爬行-可能吗?,web,apache-spark,web-crawler,Web,Apache Spark,Web Crawler,当我参加一次关于web挖掘的采访时,我问了一个有趣的问题。问题是,是否可以使用ApacheSpark对网站进行爬网 我猜想这是可能的,因为它支持Spark的分布式处理能力。面试结束后,我搜索了这个,但没有找到任何有趣的答案。用Spark可以吗?这样怎么样: 您的应用程序将获得一组网站URL作为爬虫程序的输入,如果您只是实现一个普通的应用程序,您可以按如下方式执行: 将要爬网的所有网页拆分为一个单独的站点列表,每个站点都足够小,可以很好地容纳一个线程: 例如:您必须将www.example.com

当我参加一次关于web挖掘的采访时,我问了一个有趣的问题。问题是,是否可以使用ApacheSpark对网站进行爬网

我猜想这是可能的,因为它支持Spark的分布式处理能力。面试结束后,我搜索了这个,但没有找到任何有趣的答案。用Spark可以吗?

这样怎么样:

您的应用程序将获得一组网站URL作为爬虫程序的输入,如果您只是实现一个普通的应用程序,您可以按如下方式执行:

  • 将要爬网的所有网页拆分为一个单独的站点列表,每个站点都足够小,可以很好地容纳一个线程:
    例如:您必须将www.example.com/news从20150301爬网到20150401,拆分结果可以是:[www.example.com/news/20150301,www.example.com/news/20150302,…,www.example.com/news/20150401]
  • 将每个基本url(
    www.example.com/news/20150401
    )分配给一个线程,真正的数据获取发生在线程中
  • 将每个线程的结果保存到文件系统中
  • 当应用程序成为spark应用程序时,同样的过程也会发生,但封装在spark概念中:我们可以定制一个爬行RDD,使用相同的人员:

  • 拆分站点:
    def getPartitions:Array[Partition]
    是执行拆分任务的好地方
  • 要对每个分割进行爬网的线程:
    def compute(part:Partition,context:TaskContext):迭代器[X]
    将分布到应用程序的所有执行者,并行运行
  • 将rdd保存到HDFS中
  • 最终的程序如下所示:

    class-CrawlPartition(rddId:Int,idx:Int,val-baseURL:String)扩展了分区{}
    类CrawlRDD(baseURL:String,sc:SparkContext)扩展了RDD[X](sc,Nil){
    覆盖受保护的def getPartitions:阵列[CrawlPartition]={
    val partitions=new ArrayBuffer[CrawlPartition]
    //将baseURL拆分为子集并填充分区
    托雷
    }
    覆盖def计算(部分:分区,上下文:TaskContext):迭代器[X]={
    val p=部分.asInstanceOf[爬网分区]
    val baseUrl=p.baseUrl
    新迭代器[X]{
    变量nextURL=_
    覆盖def hasNext:Boolean={
    //查找下一个url的逻辑(如果有),请填写nextURL并返回true
    //否则错误
    }          
    覆盖def next():X={
    //下一步抓取网页并在X中返回内容的逻辑
    }
    } 
    }
    }
    对象爬网{
    def main(参数:数组[字符串]){
    val sparkConf=new sparkConf().setAppName(“爬虫程序”)
    val sc=新的SparkContext(sparkConf)
    val crdd=新的爬网RDD(“baseURL”,sc)
    crdd.saveAsTextFile(“hdfs://path_here")
    sc.停止()
    }
    }
    
    Spark基本上没有给这项任务增加任何价值

    当然,您可以进行分布式爬网,但是好的爬网工具已经支持这种开箱即用的方式。Spark提供的数据结构(如RRD)在这里几乎毫无用处,仅为了启动爬网作业,您可以直接使用Thread、Mesos等,开销更少


    当然,你可以在Spark上这样做。就像你可以在Spark上做文字处理器一样,因为它是图灵完全的。。。但这并没有变得更容易。

    有一个项目,叫做

    由ApacheSpark提供支持的用于web抓取/数据mashup/验收QA的可扩展查询引擎

    希望有帮助

    是的

    查看开源项目:Sparker(spark-crawler)

    签出流/管道图。(抱歉,这是一个SVG图像,我无法在这里发布)

    该项目在问题发布时不可用,但截至2016年12月,它是一个非常活跃的项目

    是否可以使用ApacheSpark对网站进行爬网? 下面的文章可以帮助你理解为什么有人会问这样的问题,也可以帮助你回答这个问题

    • Spark framework的创建者在开创性论文[1]中写道,RDD不太适合对共享状态进行异步细粒度更新的应用程序,例如存储系统 对于web应用程序或增量web爬虫程序
    • RDD是Spark的关键组件。但是,您可以创建传统的map reduce应用程序(很少或没有滥用RDD)
    • 有一种广泛流行的分布式网络爬虫叫做Nutch[2]。Nutch是用Hadoop Map Reduce构建的(事实上,Hadoop Map Reduce是从Nutch代码库中提取出来的)
    • 如果您可以在Hadoop Map Reduce中完成一些任务,那么您也可以使用ApacheSpark来完成
    [1]
    [2]


    附言: 我是Sparker的共同创作者,也是ApacheNutch的提交人、PMC



    在设计Sparker时,我创建了一个RDD,它是基于Solr/Lucene的索引存储的代理。它使我们的爬虫数据库RDD能够对共享状态进行异步细粒度更新,否则这在本地是不可能的

    我认为公认的答案在一个基本方面是不正确的;现实生活中的大规模web抽取是一个拉动过程

    这是因为通常情况下,请求HTTP内容比构建响应要轻松得多。我已经建立了一个小程序,它能够每天抓取1600万页,有四个CPU核心和3GB RAM,而且还没有得到很好的优化。对于类似的服务器,这样的负载(每秒约200个请求)并非微不足道,通常需要进行多层优化

    例如,如果你抓取速度太快,真实的网站可能会破坏其缓存系统(缓存中没有最流行的页面,而是会充斥着抓取的长尾内容)。因此,从这个意义上说,一个好的网络刮刀总是尊重robots.txt等

    分布式爬虫的真正好处不是将一个域的工作负载拆分,而是将多个域的工作负载拆分为单个分布式进程