2010-03-21 617 views

回答

29
>>> import httplib 
>>> 
>>> def exists(site, path): 
...  conn = httplib.HTTPConnection(site) 
...  conn.request('HEAD', path) 
...  response = conn.getresponse() 
...  conn.close() 
...  return response.status == 200 
... 
>>> exists('http://www.fakedomain.com', '/fakeImage.jpg') 
False 

如果狀態是任何其他比200,資源不會在URL存在。這並不意味着它完全消失了。如果服務器返回301或302,這意味着該資源仍然存在,但位於不同的URL。要改變處理這種情況的功能,只需要將狀態檢查行更改爲return response.status in (200, 301, 302)

+2

+1,但我想象在調用'conn.request'時使用'HEAD'而不是'GET'會更有效率,因爲你只是檢查它是否存在。 –

+0

@丹尼爾,謝謝你的提示。我已經更新了代碼以使用HEAD。 – tikiboy

+0

如果您看到的錯誤類似於:**「gaierror:[Errno 8] nodename或服務器名稱已提供或未知」**請確保您的「站點」值不包含「http://」,「ftp: //'等。相反,似乎httplib會嘗試派生出正確的協議或要求指定適當的端口號(請參閱下面的其他註釋)。 – bluebinary

0

我想你可以嘗試發送一個HTTP請求的URL和讀取response.If也不例外被抓了,它可能存在。

+0

這就是我所做的,但我找不到任何特定的代碼示例。你會碰巧有嗎? – user257543

+0

@ user257543看來你已經有了一個很好的:) – Young

3

看起來像http://www.fakedomain.com/fakeImage.jpg自動重定向到http://www.fakedomain.com/index.html沒有任何錯誤。

重定向301和302響應會自動完成,而不會給予任何迴應給用戶。

請看看HTTPRedirectHandler,你可能需要繼承它來處理它。

這裏是深入Python的一個樣本:

http://diveintopython3.ep.io/http-web-services.html#redirects

+3

我認爲fakedomain.com是用於例如命名,實際上你不需要自己訪問它。:-) – Young

+1

@SpawnCxy,起初我想那樣,但是當我去那個網址時, fakeImage.jpg不存在,並且它被重定向到index.html,所以我假設它不僅僅是一個例子。 – YOU

0

我不知道你爲什麼這樣做,但無論如何:應該注意的是,僅僅因爲對「圖像」的請求成功了,並不意味着它就是你的想法(它可以重定向到任何事物,或返回任何類型的數據,並可能導致問題,這取決於您對響應所做的操作)。

對不起,我去了一個狂歡閱讀有關網上攻擊和今天如何抵禦它們:P

1

mechanize試試:

import mechanize 
br = mechanize.Browser() 
br.set_handle_redirect(False) 
try: 
br.open_novisit('http://www.fakedomain.com/fakeImage.jpg') 
print 'OK' 
except: 
print 'KO' 
7

感謝所有的答覆大家,結束了使用以下:

try: 
    f = urllib2.urlopen(urllib2.Request(url)) 
    deadLinkFound = False 
except: 
    deadLinkFound = True 
+0

短小甜美。我自己使用這個作爲我的URL字符串(約5000個)是完整的URI - 我不想太詳細。我還能夠假設我會收到404而不是重定向。不確定這將與重定向一起工作。 – Flowpoke

+1

那麼,也會在URL錯誤上給出True,即使在301,302,303錯誤上也是如此。 –

3

沒有與當文件在FTP服務器上以前的答案(ftp://url.com/file)問題,FOL

import urllib2 

def file_exists(url): 
    request = urllib2.Request(url) 
    request.get_method = lambda : 'HEAD' 
    try: 
     response = urllib2.urlopen(request) 
     return True 
    except: 
     return False 
+0

當我輸入一個錯誤的文件URL時,我無法得到任何以前的答案來返回False,但這個答案效果很好! – Darkhydro

22

下面的代碼就相當於tikiboy's answer,但使用的高級別和易於使用的requests庫:當文件在FTP,HTTP或HTTPS降脂代碼工作。

import requests 

def exists(path): 
    r = requests.head(path) 
    return r.status_code == requests.codes.ok 

print exists('http://www.fakedomain.com/fakeImage.jpg') 

requests.codes.ok等於200,所以如果你願意,你可以替換的確切狀態代碼。

requests.head如果服務器沒有響應,可能會拋出exception,所以您可能需要添加try-except構造。

此外,如果你想包括代碼301302,考慮代碼303太多,特別是如果你是​​中表示資源Linked Data。 URI可能代表一個人,但無法下載某個人,因此服務器會將您重定向到描述此人使用303 redirect的頁面。

+0

這個答案看起來是現在最簡單也是最正常的方式。請參閱http://stackoverflow.com/questions/2018026/should-i-use-urllib-or-urllib2-or-requests –

+0

在Python 3.5中與其他答案完全相反。 – Eskapp

0

這可能足以查看文件的url是否存在。

import urllib 
if urllib.urlopen('http://www.fakedomain.com/fakeImage.jpg').code == 200: 
    print 'File exists'