如何使用python取消缩短URL?

如何使用python取消缩短URL?,python,curl,youtube,hyperlink,urllib,Python,Curl,Youtube,Hyperlink,Urllib,我已经看过这条线了- 我对已解决的答案(即使用unsort.meAPI)的问题是,我将重点放在取消对youtube链接的排序上。由于unshort.me很容易使用,因此这会返回几乎90%的带有验证码的结果,而我无法解析这些结果 到目前为止,我一直坚持使用: def unshorten_url(url): resolvedURL = urllib2.urlopen(url) print resolvedURL.url #t = Test() #c = pycu

我已经看过这条线了-

我对已解决的答案(即使用unsort.meAPI)的问题是,我将重点放在取消对youtube链接的排序上。由于unshort.me很容易使用,因此这会返回几乎90%的带有验证码的结果,而我无法解析这些结果

到目前为止,我一直坚持使用:

def unshorten_url(url):
    resolvedURL = urllib2.urlopen(url)  
    print resolvedURL.url

    #t = Test()
    #c = pycurl.Curl()
    #c.setopt(c.URL, 'http://api.unshort.me/?r=%s&t=xml' % (url))
    #c.setopt(c.WRITEFUNCTION, t.body_callback)
    #c.perform()
    #c.close()
    #dom = xml.dom.minidom.parseString(t.contents)
    #resolvedURL = dom.getElementsByTagName("resolvedURL")[0].firstChild.nodeValue
    return resolvedURL.url
注意:评论中的所有内容都是我在使用unshort.me服务返回验证码链接时尝试执行的操作


是否有人知道一种更有效的方法来完成此操作而不使用open(因为它浪费带宽)?

您必须打开它,否则您将不知道它将重定向到哪个URL。正如格雷格所说:

一个短链接是进入别人数据库的钥匙;如果不查询数据库,则无法展开链接

现在谈谈你的问题

有没有人知道更有效的方法来完成这个操作 不使用open(因为这是对带宽的浪费)

更有效的方法是不关闭连接,而是在后台使用HTTP的
连接:keep-alive
保持连接打开

经过一个小测试,unshorten.me似乎考虑了
HEAD
方法,并重定向到自身:

> telnet unshorten.me 80
Trying 64.202.189.170...
Connected to unshorten.me.
Escape character is '^]'.
HEAD http://unshort.me/index.php?r=http%3A%2F%2Fbit.ly%2FcXEInp HTTP/1.1
Host: unshorten.me

HTTP/1.1 301 Moved Permanently
Date: Mon, 22 Aug 2011 20:42:46 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Location: http://resolves.me/index.php?r=http%3A%2F%2Fbit.ly%2FcXEInp
Cache-Control: private
Content-Length: 0
因此,如果您使用
HEAD
HTTP方法,而不是
GET
您将实际完成两次相同的工作

相反,您应该让连接保持活动状态,这只会为您节省一点带宽,但是肯定会节省每次建立新连接的延迟。建立TCP/IP连接的成本很高

您应该获得与未排序服务的保持活动连接的数量等于您自己的服务接收的并发连接的数量


您可以在池中管理这些连接。那是你能得到的最接近的。在TCP/IP堆栈旁边。

在该问题中使用评级最佳的答案(而不是公认的答案):

# This is for Py2k.  For Py3k, use http.client and urllib.parse instead, and
# use // instead of / for the division
import httplib
import urlparse

def unshorten_url(url):
    parsed = urlparse.urlparse(url)
    h = httplib.HTTPConnection(parsed.netloc)
    resource = parsed.path
    if parsed.query != "":
        resource += "?" + parsed.query
    h.request('HEAD', resource )
    response = h.getresponse()
    if response.status/100 == 3 and response.getheader('Location'):
        return unshorten_url(response.getheader('Location')) # changed to process chains of short urls
    else:
        return url

单行函数,使用请求库,是的,它支持递归

def unshorten_url(url):
    return requests.head(url, allow_redirects=True).url

这里是一个src代码,它考虑了几乎所有有用的拐角情况:

  • 设置自定义超时
  • 设置自定义用户代理
  • 检查是否必须使用http或https连接
  • 递归解析输入url并防止在循环中结束
src代码位于github@

欢迎评论

import logging
logging.basicConfig(level=logging.DEBUG)

TIMEOUT = 10
class UnShortenUrl:
    def process(self, url, previous_url=None):
        logging.info('Init url: %s'%url)
        import urlparse
        import httplib
        try:
            parsed = urlparse.urlparse(url)
            if parsed.scheme == 'https':
                h = httplib.HTTPSConnection(parsed.netloc, timeout=TIMEOUT)
            else:
                h = httplib.HTTPConnection(parsed.netloc, timeout=TIMEOUT)
            resource = parsed.path
            if parsed.query != "": 
                resource += "?" + parsed.query
            try:
                h.request('HEAD', 
                          resource, 
                          headers={'User-Agent': 'curl/7.38.0'}

                          )
                response = h.getresponse()
            except:
                import traceback
                traceback.print_exec()
                return url
            logging.info('Response status: %d'%response.status)
            if response.status/100 == 3 and response.getheader('Location'):
                red_url = response.getheader('Location')
                logging.info('Red, previous: %s, %s'%(red_url, previous_url))
                if red_url == previous_url:
                    return red_url
                return self.process(red_url, previous_url=url) 
            else:
                return url 
        except:
            import traceback
            traceback.print_exc()
            return None

你遇到了什么url缩短器的问题?你为什么要用unshort.me呢?你的代码应该已经工作了,它应该通过重定向到真实的url来取消对url的排序。我不明白你说的“不使用open”是什么意思。一个短链接是进入别人数据库的钥匙;如果不查询数据库,就无法扩展链接。当我阅读我引用的帖子()时,它看起来像是命令urlopen GET request整个页面,所以当我只查找链接时,这是一种带宽浪费。建议的方法对我不起作用(unshort.me),所以我决定看看是否还有其他选择。效果很好-我昨天尝试了这个方法,但没有任何效果,因为我收到了大约70%的返回错误。可能只是一件一次性的事情,这就是为什么我拒绝了它。谢谢你的回复,很抱歉我提出了多余的问题。作为跟进,我只记得为什么这种方式对我不起作用。我正在开发一个twitter应用程序,有些情况下url会被缩短两倍(这种情况会发生很多次)。例如,它将获得这个视频[u't.co/LszdhNP'],并返回这个url etsy.me/r6JBGq——我实际上需要这个链接到的最终youtube地址。你知道有什么办法可以解决这个问题吗?我的答案做了一个简单的改变。很好,这个很好用。我会更深入地研究这一点,以便更好地理解它,并在将来自己调整它。再次感谢。一些网站(如twitter)将尝试强制从http重定向到https。在这种情况下,您的解决方案将永远循环,因为所有连接都假定为http,并且将继续看到重定向头。要验证这一点,请尝试运行Unsorten_url(“”)。我建议检查parsed.scheme并选择使用httplib.HTTPSConnection()。非常感谢您提供的信息。我目前打算使用上面的Pedro Loureiro答案,因为它目前正在工作。但是,如果我遇到任何问题,我会再次提到这一点。非常感谢。我认为这个答案甚至比投票最多的答案更好。尝试使用fb.net中的url,它会返回正确的url,而另一个不做任何操作。这是一个单行程序,工作非常完美。可能是最好的答案。可能是一个奇怪的问题,但我是否应该在使用
请求后关闭连接。head
?@TitoSanz否,您可以检查代码,对于所有类型的请求,会话都已关闭(除非您自己打开会话):