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

时间:2015-03-24 14:42:27

标签: python html parsing url urlencode

许多搜索引擎通过将结果的网址添加到查询字符串来跟踪点击的网址,该网址可采用以下格式: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。对于这样的网址,这将是一个问题: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://"在结果URL
  • 中被省略

Python中提取其他网址所包含的网址的最可靠,最通用和非黑客的方法是什么?

3 个答案:

答案 0 :(得分:1)

我会尝试使用urlparse.urlparse它可能会让你大部分都在那里,而你的一些额外工作将会得到你想要的东西。

答案 1 :(得分:0)

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

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

捕获"值"部分。然后我会解码这些并检查它们与另一种模式(可能是另一种正则表达式),以查看哪一个看起来像一个URL。我会检查第一部分,然后取整个值。这样,您的模式不必考虑每种可能类型的URL(并且可能他们没有将URL与单个值字段中的其他内容组合)。这可以在指定或不指定协议的情况下工作(它取决于您的模式以确定看起来像URL的内容)。

至于第二种类型的URL ...我不认为有一种非hacky方式来解析它。您可以对整个URL进行URL解码,然后查找http://(或https://,和/或您可能运行的任何其他协议)的第二个实例。你必须决定是否有任何查询字符串是"你的"网址或跟踪链接。您还可以解码URL并尝试匹配编码值。无论哪种方式都将是凌乱的,如果他们不包括协议,它将更糟糕!如果您正在使用一组特定格式,那么您可以为它们制定出良好的规则......但如果您只是必须处理它们发生在您身上的任何事情......我不会在那里思考#39;处理第二种嵌入方式的可靠方法。

答案 2 :(得分:0)

这适合我。

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