【问题标题】:How to reliably extract URLs contained in URLs with Python?如何使用 Python 可靠地提取 URL 中包含的 URL?
【发布时间】:2015-05-27 22:27:16
【问题描述】:

许多搜索引擎通过将结果的 URL 添加到查询字符串来跟踪点击的 URL,查询字符串可以采用如下格式:http://www.example.com/result?track=http://www.stackoverflow.com/questions/ask

在上面的示例中,结果 URL 是查询字符串的一部分,但在某些情况下,它采用 http://www.example.com/http://www.stackoverflow.com/questions/ask 的形式或使用 URL 编码。

我首先尝试的方法是拆分searchengineurl.split("http://")。一些明显的问题:

  • 它将返回结果 URL 之后的查询字符串的所有部分,而不仅仅是结果 URL。这样的 URL 会出现问题:http://www.example.com/result?track=http://www.stackoverflow.com/questions/ask&showauthor=False&display=None
  • 它不区分搜索引擎跟踪 URL 的查询字符串和结果 URL 的查询字符串的任何其他部分。这将是这样的 URL 的问题:http://www.example.com/result?track=http://www.stackoverflow.com/questions/ask?showauthor=False&display=None
  • 如果在结果 URL 中省略了“http://”,则会失败

在 Python 中提取其他 URL 中包含的 URL 的最可靠、最通用和最简单的方法是什么?

【问题讨论】:

    标签: python html parsing url urlencode


    【解决方案1】:

    我会尝试使用urlparse.urlparse,它可能会让您顺利完成大部分工作,而您只需做一些额外的工作就会得到您想要的。

    【讨论】:

    • urlparse.parse_qs 会有帮助吗?还是您在寻找更强大的东西?
    【解决方案2】:

    我不具体了解 Python,但我会使用正则表达式来获取查询字符串的部分 (key=value),例如...

    (?:\?|&)[^=]+=([^&]*)
    

    这捕获了“价值”部分。然后我会对它们进行解码并根据另一种模式(可能是另一个正则表达式)检查它们,看看哪个看起来像一个 URL。我只会检查第一部分,然后取整个值。这样,您的模式就不必考虑每种可能的 URL 类型(并且可能他们没有将 URL 与单个值字段中的其他内容结合起来)。无论是否指定协议,这都应该有效(取决于您的模式来确定 URL 的外观)。

    至于第二种类型的 URL……我不认为有一种非 hacky 的方式来解析它。您可以对整个 URL 进行 URL 解码,然后查找 http://(或 https://,和/或您可能遇到的任何其他协议)的第二个实例。您必须确定任何查询字符串是“您的”URL 还是跟踪器 URL 的一部分。您也可以解码 URL 并尝试匹配编码值。无论哪种方式都会很混乱,如果它们不包含协议,情况会更糟!如果您正在使用一组特定的格式,您可以为它们制定好的规则......但如果您只需要处理它们碰巧向您抛出的任何东西......我认为没有可靠的方法来处理第二种嵌入。

    【讨论】:

      【解决方案3】:

      这对我有用。

      from urlparse import urlparse
      from urllib import unquote
      
      urls =["http://www.example.com/http://www.stackoverflow.com/questions/ask", 
      "http://www.example.com/result?track=http://www.stackoverflow.com/questions/ask&showauthor=False&display=None", 
      "http://www.example.com/result?track=http://www.stackoverflow.com/questions/ask?showauthor=False&display=None",
      "http://www.example.com/result?track=http%3A//www.stackoverflow.com/questions/ask%3Fshowauthor%3DFalse%26display%3DNonee"]
      
      def clean(url):
          path = urlparse(url).path
          index = path.find("http")
          if not index == -1:
              return path[index:]
          else:
              query = urlparse(url).query
              index = query.index("http")
              query = query[index:]
              index_questionmark = query.find("?")
              index_ampersand = query.find("&")
              if index_questionmark == -1 or index_questionmark > index_ampersand:
                  return unquote(query[:index_ampersand])
              else:
                  return unquote(query)
      
      for url in urls:
          print clean(url)
      
      > http://www.stackoverflow.com/questions/ask
      > http://www.stackoverflow.com/questions/ask
      > http://www.stackoverflow.com/questions/ask?showauthor=False&display=None
      > http://www.stackoverflow.com/questions/ask?showauthor=False&display=None
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-05
        • 1970-01-01
        • 2019-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多