urllib2.HTTPError: помилка HTTP 403: заборонено


102

Я намагаюся автоматизувати завантаження історичних даних про запаси за допомогою python. URL-адреса, яку я намагаюся відкрити, відповідає у файлі CSV, але я не в змозі відкрити за допомогою urllib2. Я спробував змінити агент користувача, як зазначено в кількох питаннях раніше, я навіть намагався прийняти файли cookie-відповіді, не пощастивши. Чи можете ви допомогти.

Примітка: той самий метод працює і для yahoo Finance.

Код:

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)

Помилка

Файл "C: \ Python27 \ lib \ urllib2.py", рядок 527, в http_error_default підняти HTTPError (req.get_full_url (), код, msg, hdrs, fp) urllib2.HTTPError: помилка HTTP 403: заборонено

Дякуємо за вашу допомогу


Ви використовуєте Windows як платформу?
Денис

Відповіді:


170

Додавши ще кілька заголовків, я зміг отримати дані:

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

Насправді він працює лише з цим додатковим заголовком:

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

Який із цих заголовків, на вашу думку, відсутній у запиті оригіналу?

1
wireshark показав, що тільки User-Agent був надісланий разом із Connection: close, Host: www.nseindia.com, Accept-Encoding: особистість
andrean

1
Запрошуємо вас. Добре, що я насправді зробив, це я перевірив URL-адресу вашого скрипту в браузері, і, як він там працював, я просто скопіював усі заголовки запитів, надіслані браузером, і додав їх сюди, і це було рішенням.
andrean

1
@Mee, ти подивився на відповідь нижче? він був адресований спеціально для python 3, перевірте, чи працює він для вас ...
andrean

1
спробуйте додати до запиту й інші заголовки (з моєї відповіді). все ж є багато інших причин, чому сервер може повернути 403, ознайомтесь і з іншими відповідями на цю тему. що стосується цілі, Google особливо важкий, начебто важко вичісувати, вони застосували багато методів, щоб запобігти вискоблюванню.
Андрій

50

Це буде працювати в 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

2
Це правда, що деякі сайти (включаючи Вікіпедію) блокують на загальних рядках агентів, що не користуються браузером, як-от "Python-urllib / xy", надісланий бібліотеками Python. Навіть простої "Mozilla" чи "Opera" зазвичай достатньо, щоб обійти це. Це, звичайно, не стосується початкового питання, але це все-таки корисно знати.
efotinis

7

Веб-сайт NSE змінився, і старі сценарії напівептимальні для поточного веб-сайту. Цей фрагмент може збирати щоденні подробиці безпеки. Деталі включають символ, тип цінних паперів, попереднє закриття, відкрита ціна, висока ціна, низька ціна, середня ціна, торгувана кількість, товарообіг, кількість торгів, обсяги доставки та співвідношення доставлених проти торгуваних у відсотках. Вони зручно представлені у вигляді списку словникової форми.

Версія Python 3.X із запитами та 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)

Крім того, це порівняно модульно і готовий до використання фрагмент.


Спасибі, чоловіче! це працювало для мене замість вищезгаданої відповіді від @andrean
Кумар, Пал

Привіт, я справді більше не знаю, куди бити голову, я спробував це рішення та багато іншого, але я все одно отримую помилку 403. Чи можна ще щось спробувати?
Франческо

Статус 403 призначений для повідомлення про те, що ваш веб-переглядач не має автентифікації для використання цієї послуги. Можливо, у вашому випадку справді потрібна автентифікація з базовим auth, oauth тощо
Supreet Sethi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.