Erreur HTTP 403 dans Python 3 Web Scraping

100

J'essayais de supprimer un site Web pour m'entraîner, mais j'ai continué à obtenir l'erreur HTTP 403 (est-ce que je pense que je suis un robot)?

Voici mon code:

#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'erreur que j'obtiens est:

 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
Josh
la source

Réponses:

208

Cela est probablement dû à mod_securityune fonction de sécurité du serveur similaire ou à une fonction de sécurité du serveur similaire qui bloque les agents utilisateurs spider / bot connus ( urllibutilise quelque chose comme python urllib/3.3.0, il est facilement détecté). Essayez de définir un agent utilisateur de navigateur connu avec:

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

Cela fonctionne pour moi.

Au fait, dans votre code, vous manquez l' ()after .readdans la urlopenligne, mais je pense que c'est une faute de frappe.

CONSEIL: puisqu'il s'agit d'un exercice, choisissez un site différent, non restrictif. Peut-être qu'ils bloquent urllibpour une raison quelconque ...

Stefano Sanfilippo
la source
Je suppose qu'il est sûr de le réutiliser reqpour plusieurs urlopenappels.
Acumenus
Il est peut-être un peu tard, mais j'ai déjà User-Agent dans mon code, cela me donne toujoursError 404: Access denied
Reema Parakh
Cela fonctionne mais je pense qu'ils doivent avoir une bonne raison de bloquer les bots et je viole leurs conditions de service
xjcl
39

Il est définitivement bloquant à cause de votre utilisation d'urllib basée sur l'agent utilisateur. La même chose m'arrive avec OfferUp. Vous pouvez créer une nouvelle classe appelée AppURLopener qui remplace l'agent utilisateur avec Mozilla.

import urllib.request

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

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

La source

zeta
la source
2
La réponse principale n'a pas fonctionné pour moi, contrairement à la vôtre. Merci beaucoup!
Tarun Uday
Cela fonctionne très bien mais je dois y attacher la configuration ssl. Comment puis-je faire cela? Avant, je viens de l'ajouter en tant que deuxième paramètre (urlopen (request, context = ctx))
Hauke
2
on dirait qu'il s'est ouvert mais il dit `` ValueError: lecture du fichier fermé ''
Martian2049
@zeta Comment avez-vous réussi à gratter OfferUp et à fournir les coordonnées géographiques nécessaires pour effectuer la recherche à partir d'un script?
CJ Travis
@CJTravis, je ne raclais pas OfferUp. J'étais juste en train de récupérer des valeurs d'article basées sur une URL exacte d'un article. Cela ne nécessitait aucune coordonnée géographique pour moi
zeta
13

"Ceci est probablement dû à mod_security ou à une fonction de sécurité de serveur similaire qui bloque les

araignée / bot

agents utilisateurs (urllib utilise quelque chose comme python urllib / 3.3.0, il est facilement détecté) "- comme déjà mentionné par 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')

Le web_byte est un objet octet renvoyé par le serveur et le type de contenu présent dans la page Web est principalement utf-8 . Par conséquent, vous devez décoder web_byte en utilisant la méthode de décodage.

Cela résout le problème complet alors que j'essayais de supprimer un site Web en utilisant PyCharm

PS -> J'utilise python 3.4

Royatirek
la source
2

Sur la base de la réponse précédente,

from urllib.request import Request, urlopen       
#specify url
url = 'https://xyz/xyz'
req = Request(url, headers={'User-Agent': 'XYZ/3.0'})
response = urlopen(req, timeout=20).read()

Cela a fonctionné pour moi en prolongeant le délai.

VICTOR IWUOHA
la source
1

Étant donné que la page fonctionne dans le navigateur et non lors de l'appel dans le programme python, il semble que l'application Web qui sert cette URL reconnaît que vous demandez le contenu non par le navigateur.

Manifestation:

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>

et le contenu de r.txt a une ligne d'état:

HTTP/1.1 403 Forbidden

Essayez de poster l'en-tête 'User-Agent' qui fausse le client Web.

REMARQUE: la page contient un appel Ajax qui crée la table que vous souhaitez probablement analyser. Vous devrez vérifier la logique javascript de la page ou simplement utiliser le débogueur de navigateur (comme l'onglet Firebug / Net) pour voir quelle URL vous devez appeler pour obtenir le contenu de la table.

Robert Lujo
la source
1

Vous pouvez essayer de deux manières. Le détail est dans ce lien .

1) Par pip

pip install - mise à niveau certifi

2) Si cela ne fonctionne pas, essayez d'exécuter une commande Cerificates.command fournie avec Python 3. * pour Mac: (Accédez à l'emplacement d'installation de python et double-cliquez sur le fichier)

open / Applications / Python \ 3. * / Install \ Certificates.command

Johnson
la source
0

Si vous vous sentez coupable d'avoir simulé l'agent utilisateur comme Mozilla (commentaire dans la première réponse de Stefano), cela pourrait également fonctionner avec un agent utilisateur non-urllib. Cela a fonctionné pour les sites que je référence:

    req = urlrequest.Request(link, headers={'User-Agent': 'XYZ/3.0'})
    urlrequest.urlopen(req, timeout=10).read()

Ma candidature consiste à tester la validité en grattant des liens spécifiques auxquels je me réfère, dans mes articles. Pas un grattoir générique.

Sudeep Prasad
la source
0

Sur la base des réponses précédentes, cela a fonctionné pour moi avec Python 3.7

from urllib.request import Request, urlopen

req = Request('Url_Link', headers={'User-Agent': 'XYZ/3.0'})
webpage = urlopen(req, timeout=10).read()

print(webpage)
Jonny_P
la source