2013-05-18 61 views
31

我試圖爲實踐取消網站,但我一直在獲取HTTP錯誤403(它是否認爲我是機器人)?Python 3中的HTTP錯誤403 Web Scraping

這裏是我的代碼:

#import requests 
import urllib.request 
from bs4 import BeautifulSoup 
#from urllib import urlopen 
import re 

webpage = urllib.request.urlopen('http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1').read 
findrows = re.compile('<tr class="- banding(?:On|Off)>(.*?)</tr>') 
findlink = re.compile('<a href =">(.*)</a>') 

row_array = re.findall(findrows, webpage) 
links = re.finall(findlink, webpate) 

print(len(row_array)) 

iterator = [] 

我得到的錯誤是:

File "C:\Python33\lib\urllib\request.py", line 160, in urlopen 
    return opener.open(url, data, timeout) 
    File "C:\Python33\lib\urllib\request.py", line 479, in open 
    response = meth(req, response) 
    File "C:\Python33\lib\urllib\request.py", line 591, in http_response 
    'http', request, response, code, msg, hdrs) 
    File "C:\Python33\lib\urllib\request.py", line 517, in error 
    return self._call_chain(*args) 
    File "C:\Python33\lib\urllib\request.py", line 451, in _call_chain 
    result = func(*args) 
    File "C:\Python33\lib\urllib\request.py", line 599, in http_error_default 
    raise HTTPError(req.full_url, code, msg, hdrs, fp) 
urllib.error.HTTPError: HTTP Error 403: Forbidden 

回答

66

這可能是因爲mod_security或一些類似服務器的安全功能,阻止已知的蜘蛛/機器人用戶代理( urllib使用類似python urllib/3.3.0的東西,很容易檢測到)。嘗試設置已知的瀏覽器用戶代理:

from urllib.request import Request, urlopen 

req = Request('http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1', headers={'User-Agent': 'Mozilla/5.0'}) 
webpage = urlopen(req).read() 

這適用於我。

順便說一下,在您的代碼中,您在urlopen行中錯過後的(),但我認爲這是一個錯字。

提示:因爲這是練習,請選擇其他非限制性網站。也許他們是阻止urllib出於某種原因...

+3

仍然沒有工作... – Martian2049

+0

我上面確切的問題,這無疑爲我工作。 – Samuurai

1

由於頁作品在瀏覽器,而不是Python程序內調用時,它似乎是Web應用程序,供應該url識別您瀏覽器請求內容不。

示範:

curl --dump-header r.txt http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1 

... 
<HTML><HEAD> 
<TITLE>Access Denied</TITLE> 
</HEAD><BODY> 
<H1>Access Denied</H1> 
You don't have permission to access ... 
</HTML> 

和r.txt內容有狀態行:

HTTP/1.1 403 Forbidden 

嘗試張貼頭 '的User-Agent',這假貨 Web客戶端。

注意:該頁面包含Ajax調用,該調用創建您可能想要解析的表。您需要檢查頁面的JavaScript邏輯,或者只需使用瀏覽器調試器(如Firebug/Net標籤)來查看需要調用哪個URL來獲取表格的內容。

21

肯定是因爲你使用基於用戶代理的urllib而被阻塞。 OfferUp同樣發生在我身上。您可以創建一個名爲AppURLopener的新類,它使用Mozilla覆蓋用戶代理。

import urllib.request 

class AppURLopener(urllib.request.FancyURLopener): 
    version = "Mozilla/5.0" 

opener = AppURLopener() 
response = opener.open('http://httpbin.org/user-agent') 

Source

+1

最熱門的答案對我來說不起作用,而你的確做到了。非常感謝! – tarunuday

+0

這工作得很好,但我需要將SSL配置附加到此。我該怎麼做呢?在我剛剛添加它作爲第二個參數(urlopen(request,context = ctx))之前 – Hauke

+0

看起來像它確實打開,但它說'ValueError:讀取已關閉的文件' – Martian2049

3

「這可能是因爲的mod_security或阻止已知

spider/bot

用戶代理一些類似的服務器安全功能(urllib的使用有點像蟒蛇的urllib/3.3。0,它很容易檢測的)」 - 如已經由斯特凡諾聖菲利波提到

from urllib.request import Request, urlopen 
url="https://stackoverflow.com/search?q=html+error+403" 
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'}) 

web_byte = urlopen(req).read() 

webpage = web_byte.decode('utf-8') 

web_byte是由服務器和存在於網頁中的內容類型返回的字節目的是大多UTF-8 因此。你需要使用解碼方法來解碼web_byte

這樣就解決了,而我在嘗試使用PyCharm

從一個網站到報廢完全問題

P.S - >我使用Python 3.4