我已经看过这个帖子了 - How can I unshorten a URL?
我对已解决的答案(即使用unshort.me API)的问题在于我专注于不驯化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
注意:注释中的所有内容都是我在使用返回captcha链接的unshort.me服务时尝试做的。
有没有人知道在不使用open的情况下完成此操作的更有效方法(因为它浪费带宽)?
答案 0 :(得分:15)
在该问题中使用评分最高的答案(不是接受的答案):
# 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
答案 1 :(得分:13)
一行功能,使用请求库,是的,它支持递归。
def unshorten_url(url):
return requests.head(url, allow_redirects=True).url
答案 2 :(得分:2)
您必须打开它,否则您将不知道它将重定向到哪个URL。正如格雷格所说:
短链接是其他人数据库的关键;您无法在不查询数据库的情况下展开链接
现在回答你的问题。
有没有人知道更有效的方法来完成此操作 不使用开放(因为它浪费带宽)?
更有效的方法是不使用HTTP Connection: 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连接昂贵。
你应该通过一些保持活跃的连接来获得与你自己的服务接收的并发连接数相等的非保护服务。
您可以在池中管理这些连接。这是你能得到的最接近的。在tweaking your kernel的TCP / IP堆栈旁边。
答案 3 :(得分:1)
这里的src代码几乎考虑了有用的极端情况:
src代码在github @ https://github.com/amirkrifa/UnShortenUrl
上欢迎评论......
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
答案 4 :(得分:0)
我可以在这里复制它,但是最好指向一个来自Dive Into Python的页面,所有这些都是关于handling redirects,这正是你想要在这里做的。