【问题标题】:Extract host name from URL using scala使用scala从URL中提取主机名
【发布时间】:2018-05-31 15:57:53
【问题描述】:

我有一个从包含以下格式的源 URL 和目标 URL 的文件中提取的 RDD:

google.de/2011/10/Extract-host       link.de/2011/10/extact-host
facebook.de/2014/11/photos           facebook.de/2014/11/name.jpg
community.cloudera.com/t5/           community.cloudera.com/t10/

这些是源 URL 和目标 URL。 我想只提取主机名,例如:

google.de                   link.de
facebook.de                 facebook.de
community.cloudera.com      community.cloudera.com

如果文件中只有一列,我知道如何提取主机名

file.flatMap(_.split("/").take(1)). 

我不确定如何将它应用于源 URL 和目标 URL。 这是我尝试过的:

file.flatMap{case(src + "\t" +  dst) => 
((split.take(1).flatMap(line => line.split("/").take(1))),
(split.takeRight(1).flatMap(line => line.split("/").take(1))))}

请告诉我如何使用 scala 提取这种格式。

谢谢!!

【问题讨论】:

  • 您希望输出的样子如何。?您是否希望源 URL 和目标 URL 都是由某个分隔符分隔的一条记录。还是希望将所有内容展平以仅提供主机名?
  • 感谢您的回复。我只需要从由一些分隔符分隔的源 URL 和目标 URL 中提取的主机名,我的输出应该看起来像我在问题中指定的那样。

标签: scala


【解决方案1】:

假设输入源和目标 url 用“\t”分隔

val result = file.map(f => {
      val urls = f.split("\t")
      if (!(urls.length < 2)) {
        val result = urls(0).takeWhile(_ != '/') + "\t" + urls(1).takeWhile(_ != '/')
        result
      } else
        null
    })

    result.collect().foreach(println(_))

【讨论】:

  • 嗨,而不是将其保存为字符串,是否可以将其映射为 (a,b) 格式?因为我需要计算链接和页面排名。
  • 映射,是指一对rdd吗?如果是,您可以通过返回一个键值对的scala元组来创建一个对rdd,如下所示。val result = file.map(f => { val urls = f.split("\t") if (!(urls .length
  • 是的,我试过了,我也可以查看记录。但是当我尝试将其保存到 .gz 格式的文件中时出现了一些错误。
  • 您好,我整理好了。感谢您的帮助:)
【解决方案2】:

面向数据框的答案:

val df_raw = spark.read
    .format("com.databricks.spark.csv")
    .option("delimiter","\t")
    .option("header", "true")
    .load("your_file.txt")

//if header is false just specify a schema
import org.apache.spark.sql.types._

val schema = StructType(
  StructField("src", StringType, true) :: 
  StructField("dst", StringType, true) :: Nil)

//and add this line to the spark.read :
//.schema(schema)

使用 udf 函数,不知道是否优化:

val get_domain = spark.udf.register("get_domain",(value:String)=> value.takeWhile(_ != '/'))

val get_domain = udf((value:String)=> value.takeWhile(_ != '/'))

并选择新列:

val df_final = df_raw
    .withColumn("src_domain",get_domain(col("src")))
    .withColumn("dst_domain",get_domain(col("dst")))

【讨论】:

  • 嗨。感谢您的答复。我有 .gz 文件。当我尝试阅读时, val df_raw = spark.read .format("com.databricks.spark.csv") .option("delimiter","\t") .option("header", "true") .load (“filename.gz”)我收到一个错误名称:编译错误消息::1:错误:定义.format(“com.databricks.spark.csv”)的非法开始。
  • 对于我的用例,我会创建一个 shell 文件来将文件解压到一个目录并从这里读取它们。但我猜你应该使用 RDD API。祝你好运。
【解决方案3】:

您可以使用模式匹配:

val pattern = """([a-zA-Z0-9\.]+)/\S*\s+([a-zA-Z0-9\.]+)/.*""".r

val srcAndDest = rdd flatMap {
  _ match {
    case pattern(src, dest) => Some(src, dest)
    case _                  => None
  }
}

【讨论】:

  • 您好,谢谢您的回答。我试过这个。但我没有检索到任何结果。
  • 从输入文件创建 rdd 的代码是什么?
  • 它的 val 文件 = sc.textFile("filename.gz")
  • 所以当你执行“val lines = srcAndDest.collect; println(lines.length);lines.foreach(println)”时 - 没有任何东西打印到控制台?
  • 很遗憾,控制台没有打印任何内容。
猜你喜欢
  • 2015-04-19
  • 2022-01-16
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多