如何在Spark SQL(Scala)中解析URL

时间:2018-08-27 14:17:38

标签: scala apache-spark

我正在使用以下函数来解析url,但会引发错误,

<html>
<head>
    <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
</head>
<body>
    Hai this is the symbol &#8804;
</body>

</html>

错误:

val b = Seq(("http://spark.apache.org/path?query=1"),("https://people.apache.org/~pwendell/spark-nightly/spark-master-docs/latest/api/sql/#negative")).toDF("url_col")
        .withColumn("host",parse_url($"url_col","HOST"))
        .withColumn("query",parse_url($"url_col","QUERY"))
        .show(false)

恳请指导如何将url解析为不同的部分。

4 个答案:

答案 0 :(得分:3)

parse_url仅作为sql而不是api 可用。请参阅parse_url

因此您应该将其用作sql查询而不是通过api进行函数调用

您应该注册数据框使用查询,如下所示

val b = Seq(("http://spark.apache.org/path?query=1"),("https://people.apache.org/~pwendell/spark-nightly/spark-master-docs/latest/api/sql/#negative")).toDF("url_col")

b.createOrReplaceTempView("temp")
spark.sql("SELECT url_col, parse_url(`url_col`, 'HOST') as HOST, parse_url(`url_col`,'QUERY') as QUERY from temp").show(false)

应该为您提供

+--------------------------------------------------------------------------------------------+-----------------+-------+
|url_col                                                                                     |HOST             |QUERY  |
+--------------------------------------------------------------------------------------------+-----------------+-------+
|http://spark.apache.org/path?query=1                                                        |spark.apache.org |query=1|
|https://people.apache.org/~pwendell/spark-nightly/spark-master-docs/latest/api/sql/#negative|people.apache.org|null   |
+--------------------------------------------------------------------------------------------+-----------------+-------+

我希望答案会有所帮助

答案 1 :(得分:3)

@Ramesh的回答是正确的,但是您可能还希望使用一些别有用心的方法来使用此功能,而无需执行SQL查询:)

事实上,“ callUDF”函数不仅会调用UDF,而且还会调用任何可用函数。

所以您可以写:

import org.apache.spark.sql._
import org.apache.spark.sql.functions._

b.withColumn("host", callUDF("parse_url", $"url_col", lit("HOST"))).
 withColumn("query", callUDF("parse_url", $"url_col", lit("QUERY"))).
 show(false)

编辑:this Pull Request合并后,您可以像正常功能一样使用parse_url。在此问题之后提出公关:)

答案 2 :(得分:1)

如前所述,当注册UDF时,您并没有获得Java函数,而是将其引入Spark中,因此必须以“火花方式”调用它。

我想建议我觉得方便的另一种方法,尤其是当您要使用selectExpr添加多个列时

val b = Seq(("http://spark.apache.org/path?query=1"),("https://people.apache.org/~pwendell/spark-nightly/spark-master-docs/latest/api/sql/#negative")).toDF("url_col")
val c = b.selectExpr("*", "parse_url(url_col, 'HOST') as host", "parse_url(url_col, 'QUERY') as query")
c.show(false)

答案 3 :(得分:0)

我创建了一个名为 bebe 的库,它通过 Scala API 公开了 parse_url 功能。

假设您有以下 DataFrame:

+------------------------------------+---------------+
|some_string                         |part_to_extract|
+------------------------------------+---------------+
|http://spark.apache.org/path?query=1|HOST           |
|http://spark.apache.org/path?query=1|QUERY          |
|null                                |null           |
+------------------------------------+---------------+

计算 URL 的不同部分:

df.withColumn("actual", bebe_parse_url(col("some_string"), col("part_to_extract")))
+------------------------------------+---------------+----------------+
|some_string                         |part_to_extract|actual          |
+------------------------------------+---------------+----------------+
|http://spark.apache.org/path?query=1|HOST           |spark.apache.org|
|http://spark.apache.org/path?query=1|QUERY          |query=1         |
|null                                |null           |null            |
+------------------------------------+---------------+----------------+