2011-08-22 13 views
5

私はすでにこのスレッドを見てきました - 解決の答え(つまりunshort.me APIを使用している)とのHow can I unshorten a URL?pythonを使用してURLの短縮を解除するにはどうすればよいですか?

私の問題は、私はunshorteningユーチューブリンクに焦点を当てていますということです。 unshort.meは簡単に使用されるので、解決できないcaptchaを使って結果のほぼ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サービスを使用するときに実行しようとしたものです。

誰もがオープンを使わずにこの操作を完了すると効率的な方法を知っていますか(帯域幅の浪費なので)。

+0

何のURL短縮サービスを持っていますか?とにかくunshort.meを使っているのはなぜですか?あなたのコードはすでに動作しているはずです。本当のURLへのリダイレクトに従うことでURLの脆弱性を解消する必要があります。 – zeekay

+0

私はあなたが「オープンを使わない」という意味を理解していません。短いリンクは他人のデータベースへの鍵です。データベースに問い合わせることなくリンクを拡張することはできません。 –

+0

私が参照した記事(http://stackoverflow.com/questions/4201062/how-can-i-unshorten-a-url-using-python)を読むと、そのコマンドのように見えます。urlopen GETはページ全体をリクエストします私が探しているのはリンクですので、帯域幅の無駄です。提案された方法は私のために働いていませんでした(unshort.me)ので、他の選択肢があるかどうか確認することにしました。 – brandonmat

答えて

14

その質問で最高評価の回答(不可の回答)を使用してください:

# 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

魅力的なように働いた - 私は戻って約70%でエラーを受け取っていたので、私は無駄にこの昨日試してみました。私はそれを断ち切ったのです。ご返信ありがとうございました。私の冗長な質問を申し訳ありません。 – brandonmat

+2

フォローアップとして、なぜこの方法が私にとってうまくいかなかったのか覚えています。私はツイッターアプリケーションで作業しており、URLが2回短縮されている(かなりの回数が発生する)場合があります。たとえば、このビデオ[u't.co/LszdhNP ']を取得し、このURLを返すetsy.me/r6JBGq - 実際にはこのリンク先の最終的なYouTubeアドレスが必要です。あなたはこれを回避する方法を知っていますか? – brandonmat

+2

簡単な変更は私の答えで行われました –

2

これを開く必要があります。そうでないと、リダイレクト先のURLがわかりません。 Gregは次のように書いています。

短いリンクは他の人のデータベースの鍵です。データベースを照会せずにリンクを展開することはできません

今質問しますか?

誰もこの操作を完了するためのより効率的な方法を知っていますか? オープンを使用せずに(帯域幅の無駄ですから)

より効率的な方法は、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 

だからではなくGETHEAD HTTPメソッド、を使用する場合は必要になります実際には2回同じ作業を行うことになります

代わりに、あなたはあなたに少しだけ帯域幅を節約なる、生きて接続を維持する必要がありますが、何それはは確かに保存されますと、新しい接続を毎回確立するレイテンシーです。 TCP/IP接続を確立するのは高価なです。

あなたは、自分のサービスが受け取る同時接続数に等しい数の偽造されていないサービスへの接続を数多く残すべきです。

プール内でこれらの接続を管理できます。それはあなたが得られる最も近いものです。 tweaking your kernelのTCP/IPスタックの横にあります。

+0

情報をありがとうございます。私は現在、当面は働いているので、上記のPedro Loureiroの答えを使用するつもりです。しかし、もし私が何か問題に遭遇すれば、私はこれを参照します。とても有難い。 – brandonmat

0

handling redirectsすべてについて、私はここでそれを複製することができ、それが飛び込むのPythonからページにあなたを指すように、おそらく良いでしょうこれはあなたがここでやりたいことです。

10

1行の関数は、要求ライブラリを使用し、はい、再帰をサポートします。

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

で動作します。私はこの答えが最も投票された答えよりも優れていると思います。 fb.netのURLで試してみてください。正しいURLが返されますが、他のURLは何もしません。 – lenhhoxung

+0

これは1ライナーであり、完璧に動作します。おそらく最高の答え。 – Aventinus

1

ほとんど有益なコーナーケースの考慮したSRCコード:

  • は、カスタムタイムアウトを設定します。
  • カスタムユーザーエージェントを設定します。
  • httpまたはhttps接続を使用する必要があるかどうかを確認します。
  • は、入力urlを再帰的に解決し、ループ内での終了を防止します。 https://github.com/amirkrifa/UnShortenUrl

    コメントは歓迎されている@

の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 
関連する問題