2011-08-22 37 views
5

Tôi đã xem chủ đề này - How can I unshorten a URL?Tôi làm cách nào để rút ngắn URL bằng python?

Vấn đề của tôi với câu trả lời được giải quyết (sử dụng unshort.me API) là tôi tập trung vào liên kết unshortening youtube. Vì unshort.me được sử dụng dễ dàng, điều này trả về gần 90% kết quả với captchas mà tôi không thể giải quyết được.

Cho đến nay tôi bị mắc kẹt với việc sử dụng:

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 

Lưu ý: tất cả mọi thứ trong các ý kiến ​​là những gì tôi đã cố gắng để làm gì khi sử dụng dịch vụ unshort.me được trở về liên kết mã xác nhận khác.

Có ai biết cách hiệu quả hơn để hoàn thành thao tác này mà không sử dụng mở (vì nó lãng phí băng thông) không?

+0

shortener url Những gì bạn đang gặp rắc rối với? Tại sao bạn sử dụng unshort.me anyways? Mã của bạn đã hoạt động, mã này sẽ hủy kích hoạt url bằng cách theo dõi chuyển hướng đến url thực. – zeekay

+0

Tôi không hiểu ý bạn là "không sử dụng mở". Một liên kết ngắn là chìa khóa vào cơ sở dữ liệu của người khác; bạn không thể mở rộng liên kết mà không cần truy vấn cơ sở dữ liệu. –

+0

Khi tôi đọc bài đăng mà tôi đã tham chiếu (http://stackoverflow.com/questions/4201062/how-can-i-unshorten-a-url-using-python), nó được xem như lệnh đó, urlopen GET yêu cầu toàn bộ trang vì vậy lãng phí băng thông khi tất cả những gì tôi đang tìm kiếm là liên kết. Phương pháp được đề xuất không hoạt động đối với tôi (unshort.me) nên tôi quyết định xem có phương án nào khác không. – brandonmat

Trả lời

14

Sử dụng các câu trả lời đánh giá tốt nhất (không phải là câu trả lời được chấp nhận) trong câu hỏi rằng:

# 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 
+0

Làm việc như một sự quyến rũ - Tôi đã thử điều này ngày hôm qua để không có kết quả kể từ khi tôi nhận được lỗi trên khoảng 70% lợi nhuận. Có thể chỉ là một điều một lần và đó là lý do tại sao tôi bác bỏ nó. Cảm ơn bạn đã trả lời và xin lỗi vì câu hỏi dư thừa của tôi. – brandonmat

+2

Theo dõi, tôi chỉ nhớ tại sao cách này không hiệu quả với tôi. Tôi đang làm việc trên một ứng dụng twitter và có những trường hợp url được rút ngắn hai lần (điều này xảy ra một số lần đáng kể). Ví dụ: nó sẽ nhận được video này [u't.co/LszdhNP '] và trả về url này etsy.me/r6JBGq - nơi tôi thực sự cần địa chỉ youtube cuối cùng mà liên kết này đến. Bạn có biết cách nào để giải quyết vấn đề này không? – brandonmat

+2

một thay đổi đơn giản đã được thực hiện trong câu trả lời của tôi –

2

Bạn KHÔNG phải mở nó, nếu không bạn sẽ không biết URL sẽ chuyển hướng đến. Khi Greg đặt nó:

Liên kết ngắn là chìa khóa vào cơ sở dữ liệu của người khác; bạn không thể mở rộng liên kết mà không cần truy vấn cơ sở dữ liệu

Bây giờ cho câu hỏi của bạn.

Có ai biết cách hiệu quả hơn để hoàn thành thao tác này mà không sử dụng mở (vì nó lãng phí băng thông) không?

Cách hiệu quả hơn là không đóng kết nối, giữ nó ở chế độ nền, bằng cách sử dụng HTTP Connection: keep-alive.

Sau một thử nghiệm nhỏ, unshorten.me dường như để có những phương pháp HEAD vào tài khoản và thực hiện một chuyển hướng với bản thân:

> 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 

Vì vậy, nếu bạn sử dụng phương pháp HEAD HTTP, thay vì GET, bạn sẽ thực sự kết thúc công việc tương tự hai lần.

Thay vào đó, bạn nên giữ cho các kết nối còn sống, mà bạn sẽ tiết kiệm được chỉ một chút băng thông, nhưng những gì nó sẽ chắc chắn tiết kiệm là độ trễ của việc thiết lập một kết nối mới mỗi lần. Thiết lập kết nối TCP/IP là đắt tiền.

Bạn nên thoát khỏi một số kết nối được giữ liên tục đến dịch vụ chưa được kết hợp bằng số lượng kết nối đồng thời mà dịch vụ của riêng bạn nhận được.

Bạn có thể quản lý các kết nối này trong một hồ bơi. Đó là gần nhất bạn có thể nhận được. Bên cạnh ngăn xếp TCP/IP của tweaking your kernel.

+0

Tuyệt vời cảm ơn bạn đã cung cấp thông tin. Tôi hiện đang sử dụng Pedro Loureiro câu trả lời ở trên vì nó đang làm việc trong thời gian này. Nhưng tôi sẽ nói lại điều này nếu tôi gặp phải bất kỳ vấn đề nào. Nhiều đánh giá cao. – brandonmat

0

tôi có thể sao chép nó ở đây, nhưng nó có thể là tốt hơn để chỉ cho bạn đến một trang từ Dive Into Python, tất cả về handling redirects , đó là chính xác những gì bạn muốn làm ở đây.

10

một chức năng dòng, sử dụng thư viện yêu cầu và có, nó hỗ trợ đệ quy.

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

Tôi nghĩ câu trả lời này thậm chí còn tốt hơn câu trả lời được bình chọn nhiều nhất. Hãy thử với các url từ fb.net và nó trả về url chính xác trong khi cái kia không làm gì cả. – lenhhoxung

+0

Đây là một lớp lót và hoạt động hoàn hảo. Có lẽ câu trả lời tốt nhất. – Aventinus

1

Đây mã src mà sẽ đưa vào tài khoản của hầu hết các trường hợp góc hữu ích:

  • thiết lập một Timeout tùy chỉnh.
  • đặt Đại lý người dùng tùy chỉnh.
  • kiểm tra xem chúng tôi có phải sử dụng kết nối http hoặc https hay không.
  • giải quyết đệ quy url đầu vào và ngăn kết thúc trong vòng lặp.

Mã src là trên github @https://github.com/amirkrifa/UnShortenUrl

ý kiến ​​được hoan nghênh ...

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 
Các vấn đề liên quan