124 votes

urllib2.HTTPError : Erreur HTTP 403 : Interdit

J'essaie d'automatiser le téléchargement de données boursières historiques en utilisant python. L'URL que j'essaie d'ouvrir répond avec un fichier CSV, mais je suis incapable de l'ouvrir en utilisant urllib2. J'ai essayé de changer l'agent utilisateur comme indiqué dans quelques questions précédentes, j'ai même essayé d'accepter les cookies de réponse, sans succès. Pouvez-vous m'aider ?

Note : La même méthode fonctionne pour yahoo Finance.

Code :

import urllib2,cookielib

site= "http://www.nseindia.com/live_market/dynaContent/live_watch/get_quote/getHistoricalData.jsp?symbol=JPASSOCIAT&fromDate=1-JAN-2012&toDate=1-AUG-2012&datePeriod=unselected&hiddDwnld=true"

hdr = {'User-Agent':'Mozilla/5.0'}

req = urllib2.Request(site,headers=hdr)

page = urllib2.urlopen(req)

Erreur

Dossier " C:\Python27\lib\urllib2.py ", ligne 527, dans http_error_default raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) urllib2.HTTPError : Erreur HTTP 403 : Interdit

Merci pour votre aide

191voto

andrean Points 6199

En ajoutant quelques en-têtes supplémentaires, j'ai pu obtenir les données :

import urllib2,cookielib

site= "http://www.nseindia.com/live_market/dynaContent/live_watch/get_quote/getHistoricalData.jsp?symbol=JPASSOCIAT&fromDate=1-JAN-2012&toDate=1-AUG-2012&datePeriod=unselected&hiddDwnld=true"
hdr = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
       'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
       'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
       'Accept-Encoding': 'none',
       'Accept-Language': 'en-US,en;q=0.8',
       'Connection': 'keep-alive'}

req = urllib2.Request(site, headers=hdr)

try:
    page = urllib2.urlopen(req)
except urllib2.HTTPError, e:
    print e.fp.read()

content = page.read()
print content

En fait, cela fonctionne avec ce seul en-tête supplémentaire :

'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

68voto

Eish Points 991

Cela fonctionnera dans Python 3

import urllib.request

user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'

url = "http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers"
headers={'User-Agent':user_agent,} 

request=urllib.request.Request(url,None,headers) #The assembled request
response = urllib.request.urlopen(request)
data = response.read() # The data u need

13voto

djinn Points 233

Le site web de NSE a changé et les anciens scripts sont semi-optimaux au site web actuel. Ce snippet peut rassembler les détails quotidiens de la sécurité. Les détails comprennent le symbole, le type de titre, la clôture précédente, le prix d'ouverture, le prix le plus élevé, le prix le plus bas, le prix moyen, la quantité négociée, le chiffre d'affaires, le nombre de transactions, les quantités livrables et le rapport entre les quantités livrées et négociées en pourcentage. Ces données sont présentées sous la forme d'une liste de dictionnaire.

Version Python 3.X avec requêtes et BeautifulSoup

from requests import get
from csv import DictReader
from bs4 import BeautifulSoup as Soup
from datetime import date
from io import StringIO 

SECURITY_NAME="3MINDIA" # Change this to get quote for another stock
START_DATE= date(2017, 1, 1) # Start date of stock quote data DD-MM-YYYY
END_DATE= date(2017, 9, 14)  # End date of stock quote data DD-MM-YYYY

BASE_URL = "https://www.nseindia.com/products/dynaContent/common/productsSymbolMapping.jsp?symbol={security}&segmentLink=3&symbolCount=1&series=ALL&dateRange=+&fromDate={start_date}&toDate={end_date}&dataType=PRICEVOLUMEDELIVERABLE"

def getquote(symbol, start, end):
    start = start.strftime("%-d-%-m-%Y")
    end = end.strftime("%-d-%-m-%Y")

    hdr = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
         'Referer': 'https://cssspritegenerator.com',
         'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
         'Accept-Encoding': 'none',
         'Accept-Language': 'en-US,en;q=0.8',
         'Connection': 'keep-alive'}

    url = BASE_URL.format(security=symbol, start_date=start, end_date=end)
    d = get(url, headers=hdr)
    soup = Soup(d.content, 'html.parser')
    payload = soup.find('div', {'id': 'csvContentDiv'}).text.replace(':', '\n')
    csv = DictReader(StringIO(payload))
    for row in csv:
        print({k:v.strip() for k, v in row.items()})

 if __name__ == '__main__':
     getquote(SECURITY_NAME, START_DATE, END_DATE)

En outre, il s'agit d'un snippet relativement modulaire et prêt à l'emploi.

7voto

archit jain Points 111

Cette erreur se produit généralement lorsque le serveur que vous sollicitez ne sait pas d'où vient la demande, le serveur fait cela pour éviter toute visite indésirable. Vous pouvez contourner cette erreur en définissant un en-tête et en le passant dans urllib.request

Voici le code :

#defining header
header= {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) ' 
      'AppleWebKit/537.11 (KHTML, like Gecko) '
      'Chrome/23.0.1271.64 Safari/537.11',
      'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
      'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
      'Accept-Encoding': 'none',
      'Accept-Language': 'en-US,en;q=0.8',
      'Connection': 'keep-alive'}

#the URL where you are requesting at
req = urllib.request.Request(url=your_url, headers=header) 
page = urllib.request.urlopen(req).read()

2voto

Yoshi Wannabe Points 21

Il y a une chose qui vaut la peine d'essayer, c'est juste de mettre à jour la version de python. L'un de mes scripts de crawling a cessé de fonctionner avec 403 sur Windows 10 il y a quelques mois. Tout user_agents n'a pas aidé et j'étais sur le point d'abandonner le scripts. Aujourd'hui, j'ai essayé le même scripts sur Ubuntu avec Python (3.8.5 - 64 bit) et cela a fonctionné sans erreur. La version de Python de Windows était un peu ancienne (3.6.2 - 32 bits). Après avoir mis à jour le python sur Windows 10 à 3.9.5 - 64bit, je ne vois plus les 403. Si vous l'essayez, n'oubliez pas de lancer "pip freeze > requirements.txt" pour exporter les entrées du paquet. Je l'ai oublié bien sûr. Ce post est un rappel pour moi aussi quand la 403 reviendra dans le futur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X