2013-05-18 10 views
31

Stavo cercando di cancellare un sito Web per esercitarmi, ma ho continuato a ottenere l'errore HTTP 403 (pensa che sia un bot)?Errore HTTP 403 in Python 3 Web Scraping

Ecco il mio codice:

#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 = [] 

L'errore che ottengo è:

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 

risposta

66

Questo è probabilmente a causa di mod_security o di qualche funzione di sicurezza del server simile che blocca noti spider/bot user agent (urllib utilizza qualcosa come python urllib/3.3.0, è facilmente rilevabile). Provate ad impostare un noto agente utente del browser con:

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() 

Questo funziona per me.

A proposito, nel tuo codice manca lo () dopo il .read nella riga urlopen, ma penso che sia un refuso.

SUGGERIMENTO: poiché si tratta di esercizio, scegliere un sito diverso e non limitativo. Forse stanno bloccando urllib per qualche motivo ...

+3

ancora non funziona ... – Martian2049

+0

ho avuto il problema esatta e questo sicuramente funziona per me. – Samuurai

1

Poiché la pagina funziona nel browser e non quando si chiama all'interno del programma python, sembra che l'app Web che serve che url riconosca che si richiede il contenuto non dal browser.

Dimostrazione:

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> 

e il contenuto in r.txt ha riga di stato:

HTTP/1.1 403 Forbidden 

Prova intestazione distacco 'User-Agent', che falsi client web.

NOTA: La pagina contiene una chiamata Ajax che crea la tabella che si desidera analizzare. Avrai bisogno di controllare la logica javascript della pagina o semplicemente usando il debugger del browser (come la scheda Firebug/Net) per vedere quale URL devi chiamare per ottenere il contenuto del tavolo.

21

Definitivamente sta bloccando l'utilizzo di urllib in base al programma utente. Questa stessa cosa mi sta succedendo con OfferUp. Puoi creare una nuova classe chiamata AppURLopener che sovrascrive lo user-agent con 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

La risposta migliore non ha funzionato per me, mentre il tuo ha funzionato. Molte grazie! – tarunuday

+0

Funziona bene ma ho bisogno di allegare la configurazione ssl a questo. Come faccio a fare questo? Prima di aggiungerlo come secondo parametro (urlopen (request, context = ctx)) – Hauke

+0

sembra aperto ma dice 'ValueError: read of closed file' – Martian2049

3

"Questo è probabilmente a causa di mod_security o qualche caratteristica di sicurezza del server simile che blocca noti

spider/bot

agenti utente (urllib utilizza qualcosa come pitone urllib/3.3.0, è facilmente rilevabile)" - come già detto da Stefano Sanfilippo

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') 

Il web_byte è un oggetto byte restituito dal server e il tipo di contenuto presente nel sito è principalmente utf-8 conseguenza. è necessario decodificare web_byte utilizzando il metodo di decodifica.

Questo risolve il problema completo mentre facevo cercando di scarto da un sito web utilizzando PyCharm

P.S -> Io uso python 3.4

Problemi correlati