如何可靠地提取包含 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://")
。一些明显的问题:
- 它将 return 结果 URL 之后的查询字符串的所有部分,而不仅仅是结果 URL。这将是一个像这样的 URL 的问题:
http://www.example.com/result?track=http://www.whosebug.com/questions/ask&showauthor=False&display=None
- 它不区分搜索引擎跟踪 URL 的查询字符串和结果 URL 的查询字符串的任何其他部分。这将是一个像这样的 URL 的问题:
http://www.example.com/result?track=http://www.whosebug.com/questions/ask?showauthor=False&display=None
- 如果在结果 URL
中省略 "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
许多搜索引擎通过将结果的 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://")
。一些明显的问题:
- 它将 return 结果 URL 之后的查询字符串的所有部分,而不仅仅是结果 URL。这将是一个像这样的 URL 的问题:
http://www.example.com/result?track=http://www.whosebug.com/questions/ask&showauthor=False&display=None
- 它不区分搜索引擎跟踪 URL 的查询字符串和结果 URL 的查询字符串的任何其他部分。这将是一个像这样的 URL 的问题:
http://www.example.com/result?track=http://www.whosebug.com/questions/ask?showauthor=False&display=None
- 如果在结果 URL 中省略 "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