如何可靠地提取包含 Python 的 URL 中的 URL?

How to reliably extract URLs contained in URLs with Python?

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

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

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

在 Python 中提取包含在其他 URL 中的 URL 的最可靠、通用且非 hacky 的方法是什么?

我会尝试使用 urlparse.urlparse 它可能会帮助您完成大部分工作,并且您需要做一些额外的工作才能得到您想要的。

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

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

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

至于第二种 URL... 我认为没有一种简单的方法来解析它。您可以 URL-解码整个 URL,然后查找 http://(或 https://,and/or 您可能 运行 的任何其他协议的第二个实例穿过)。您必须决定任何查询字符串是 "your" URL 还是跟踪器 URL 的一部分。您也可以 not 解码 URL 并尝试匹配编码值。无论哪种方式都会很混乱,如果他们不包括协议,那就更糟了!如果你正在处理一组特定的格式,你可以为它们制定好的规则......但是如果你只需要处理它们碰巧扔给你的任何东西......我认为没有可靠的方法来处理第二种嵌入。

这对我有用。

from urlparse import urlparse
from urllib import unquote

urls =["http://www.example.com/http://www.whosebug.com/questions/ask", 
"http://www.example.com/result?track=http://www.whosebug.com/questions/ask&showauthor=False&display=None", 
"http://www.example.com/result?track=http://www.whosebug.com/questions/ask?showauthor=False&display=None",
"http://www.example.com/result?track=http%3A//www.whosebug.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.whosebug.com/questions/ask
> http://www.whosebug.com/questions/ask
> http://www.whosebug.com/questions/ask?showauthor=False&display=None
> http://www.whosebug.com/questions/ask?showauthor=False&display=None