2014-10-09 45 views
1

關於此主題,SO上有很多問題,但沒有一個回答以下問題。檢查與Python請求正常的URL可以很容易地像這樣來完成:如果存在URL,請在Python中檢查

print requests.head('https://www.facebook.com/pixabay').status_code 

的200狀態碼意味着頁面存在。在這個特殊情況下,這是Facebook上的粉絲頁面。

嘗試這與Facebook上的普通用戶配置文件可以正常工作,也:

print requests.head('https://www.facebook.com/steinberger.simon').status_code 

不過,也有導致404個狀態碼(看似隨機的)用戶配置文件,儘管普通瀏覽器返回一個200 :

print requests.head('https://www.facebook.com/drcarl').status_code 

使用與用戶代理字符串自定義頁眉或檢查與其他方法的URL都無法以同樣的方式:

import requests, urllib, urllib2 

url = 'https://www.facebook.com/drcarl' 

print requests.head(url).status_code 

# using an User-Agent string 
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36' } 
print requests.head(url, headers=headers).status_code 

# using GET instead if HEAD as request method 
print requests.get(url, stream=True).status_code 

# using urllib 
print urllib.urlopen(url).getcode() 

# using urllib2 
try: 
    r = urllib2.urlopen(url) 
    print r.getcode() 
except urllib2.HTTPError as e: 
    print e.code 

還有其他一些使用上述方法無法解釋的URL的例子。其中之一是這樣的:http://www.rajivbajaj.net/ 它可以在所有瀏覽器中使用200狀態碼完美工作,但對於上述所有Python方法,結果爲403。

我想寫一個可靠的URL驗證器,但我不明白爲什麼這些URL失敗這些測試。有任何想法嗎?

+0

你應該問的Facebook對他們的HTTP API(如果有的話)。如果'HEAD'或'GET'在Python(或curl)中返回404 Not Found',那麼我們就無能爲力了。 – 2014-10-09 08:44:06

+0

我不能重現你的錯誤,總是得到200.嘗試在任何請求之前使用'logging.basicConfig(level = logging.DEBUG)'調試請求。 – xbello 2014-10-09 08:49:44

+0

記錄沒有給出任何新的結果。但是,我找到了失敗的FB URL的原因:未在Facebook上進行身份驗證時,非公開概要文件將返回404。 – 2014-10-09 11:36:11

回答

2

我認爲瀏覽器和python編寫的代碼之間的區別是基礎的HTTP請求。 python代碼無法正常工作,因爲構建的HTTP請求與瀏覽器生成的HTTP請求不完全相同。

添加顧客的頭文件(使用你提供的一個)

print requests.get(url, headers=headers).status_code 

它工作在我的本地端的URL http://www.rajivbajaj.net/,得到200

在這個例子中,我猜的網站爲某些用戶代理做了一些特殊的事情。

+0

*大聲笑*我不相信這個!這可能是請求方法+頭的唯一組合,我似乎錯過了!例如。一個HEAD請求不能使用這個頭文件 - 仍然是403.謝謝Jacky!順便說一句:我還發現Facebook問題的原因:當未經過身份驗證時,Facebook針對非公開個人資料發佈404。這很奇怪,但Facebook確實如此,如果有人知道...... – 2014-10-09 11:35:15

0

下面的代碼將幫助您

def check_site_exist(self, url): 
    try: 
     url_parts = urlparse(url) 
     request = requests.head("://".join([url_parts.scheme, url_parts.netloc])) 
     return request.status_code == HTTPStatus.OK 
    except: 
     return False; 
相關問題