urllib2.HTTPError: Kesalahan HTTP 403: Terlarang

102

Saya mencoba untuk mengotomatiskan pengunduhan data stok historis menggunakan python. URL yang saya coba buka merespons dengan file CSV, tetapi saya tidak dapat membuka menggunakan urllib2. Saya telah mencoba mengubah agen pengguna seperti yang ditentukan dalam beberapa pertanyaan sebelumnya, saya bahkan mencoba menerima cookie tanggapan, tidak berhasil. Bisakah Anda membantu.

Catatan: Metode yang sama berfungsi untuk yahoo Finance.

Kode:

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)

Kesalahan

File "C: \ Python27 \ lib \ urllib2.py", baris 527, di http_error_default angkat HTTPError (req.get_full_url (), kode, msg, hdrs, fp) urllib2.HTTPError: HTTP Error 403: Forbidden

Terima kasih atas bantuannya

kumar
sumber
Apakah Anda menggunakan windows sebagai platform?
Denis

Jawaban:

170

Dengan menambahkan beberapa tajuk lagi saya bisa mendapatkan data:

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

Sebenarnya, ini berfungsi hanya dengan satu tajuk tambahan ini:

'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
andrean
sumber
Manakah dari header berikut yang menurut Anda hilang dari permintaan awal?
1
wireshark menunjukkan bahwa hanya User-Agent yang dikirim, bersama dengan Connection: close, Host: www.nseindia.com, Accept-Encoding: identity
andrean
1
Sama-sama, yang sebenarnya saya lakukan adalah memeriksa url dari skrip Anda di browser, dan saat berfungsi di sana, saya baru saja menyalin semua header permintaan yang dikirim browser, dan menambahkannya di sini, dan itulah solusinya.
andrean
1
@Mee apakah Anda melihat jawaban di bawah ini? itu ditujukan khusus untuk python 3, periksa apakah itu bekerja untuk Anda ...
andrean
1
coba tambahkan tajuk lain (dari jawaban saya) juga ke permintaan. masih ada banyak alasan lain mengapa server mungkin mengembalikan 403, lihat jawaban lain tentang topik ini juga. Adapun targetnya, google terutama adalah yang sulit, agak sulit untuk dikikis, mereka telah menerapkan banyak metode untuk mencegah gesekan.
andrean
50

Ini akan bekerja dengan 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
Eish
sumber
2
Memang benar bahwa beberapa situs (termasuk Wikipedia) memblokir string umum agen pengguna non-browser, seperti "Python-urllib / xy" yang dikirim oleh pustaka Python. Bahkan "Mozilla" atau "Opera" biasa sudah cukup untuk melewati itu. Ini tidak berlaku untuk pertanyaan awal, tentu saja, tapi tetap berguna untuk diketahui.
efotinis
7

Situs web NSE telah berubah dan skrip lama semi-optimal untuk situs web saat ini. Cuplikan ini dapat mengumpulkan detail keamanan harian. Rincian termasuk simbol, jenis keamanan, penutupan sebelumnya, harga terbuka, harga tinggi, harga rendah, harga rata-rata, kuantitas yang diperdagangkan, omset, jumlah perdagangan, jumlah yang dapat dikirim dan rasio persentase yang dikirim vs yang diperdagangkan. Ini dengan mudah disajikan sebagai daftar bentuk kamus.

Versi Python 3.X dengan permintaan dan 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)

Selain itu, ini relatif modular dan potongan yang siap digunakan.

Salam Sethi
sumber
Terima kasih sobat! ini berhasil untuk saya daripada jawaban di atas dari @andrean
Nitish Kumar Pal
Hai, saya benar-benar tidak tahu harus membenturkan kepala ke mana lagi, saya sudah mencoba solusi ini dan banyak lagi, tetapi saya terus mendapatkan kesalahan 403. Apakah ada hal lain yang bisa saya coba?
Francesco
Status 403 dimaksudkan untuk menginformasikan bahwa browser Anda tidak diautentikasi untuk menggunakan layanan ini. Mungkin dalam kasus Anda, itu benar-benar memerlukan otentikasi dengan autentikasi dasar, oauth dll.
Supreet Sethi