urllib2.HTTPError: HTTP Error 403: Forbidden


102

Tôi đang cố gắng tự động tải xuống dữ liệu cổ phiếu lịch sử bằng python. URL tôi đang cố mở phản hồi bằng tệp CSV, nhưng tôi không thể mở bằng urllib2. Tôi đã thử thay đổi tác nhân người dùng như được chỉ định trong một vài câu hỏi trước đó, thậm chí tôi đã cố gắng chấp nhận cookie phản hồi nhưng không may mắn. Bạn có thể vui lòng giúp đỡ.

Lưu ý: Phương pháp tương tự cũng hoạt động đối với yahoo Finance.

Mã:

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)

lỗi

Tệp "C: \ Python27 \ lib \ urllib2.py", dòng 527, trong http_error_default nâng HTTPError (req.get_full_url (), code, msg, hdrs, fp) urllib2.HTTPError: HTTP Error 403: Forbidden

Cảm ơn vì sự hỗ trợ của bạn


Bạn có sử dụng cửa sổ làm nền tảng không?
Denis

Câu trả lời:


170

Bằng cách thêm một vài tiêu đề nữa, tôi đã có thể lấy dữ liệu:

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

Trên thực tế, nó hoạt động chỉ với một tiêu đề bổ sung này:

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

Bạn nghĩ rằng tiêu đề nào trong số những tiêu đề này bị thiếu so với yêu cầu ban đầu?

1
Wirehark cho thấy rằng chỉ Người dùng-Tác nhân được gửi, cùng với Kết nối: đóng, Máy chủ: www.nseindia.com, Chấp nhận-Mã hóa: nhận dạng
andrean

1
Bạn được chào đón, những gì tôi thực sự đã làm là tôi đã kiểm tra url từ tập lệnh của bạn trong một trình duyệt và khi nó hoạt động ở đó, tôi chỉ sao chép tất cả các tiêu đề yêu cầu mà trình duyệt đã gửi và thêm chúng vào đây và đó là giải pháp.
andrean

1
@Mee bạn có xem qua câu trả lời bên dưới không? nó đã được giải quyết cụ thể cho python 3, hãy kiểm tra xem nó có phù hợp với bạn không ...
andrean 19/01

1
hãy thử thêm các tiêu đề khác (từ câu trả lời của tôi) cũng như vào yêu cầu. vẫn còn nhiều lý do khác khiến máy chủ có thể trả về 403, hãy xem các câu trả lời khác về chủ đề này. đối với mục tiêu, google đặc biệt là một mục tiêu khó, khá khó cạo, họ đã thực hiện nhiều phương pháp để ngăn chặn việc cạo.
andrean

50

Điều này sẽ hoạt động trong 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
Đúng là một số trang web (bao gồm cả Wikipedia) chặn các chuỗi tác nhân người dùng không phải trình duyệt phổ biến, chẳng hạn như "Python-urllib / xy" được gửi bởi các thư viện của Python. Ngay cả một "Mozilla" hoặc "Opera" đơn giản thường đủ để vượt qua điều đó. Tất nhiên, điều này không áp dụng cho câu hỏi ban đầu, nhưng nó vẫn hữu ích khi biết.
efotinis

7

Trang web của NSE đã thay đổi và các tập lệnh cũ hơn là bán tối ưu cho trang web hiện tại. Đoạn mã này có thể thu thập thông tin chi tiết hàng ngày về bảo mật. Thông tin chi tiết bao gồm ký hiệu, loại chứng khoán, đóng trước, giá mở, giá cao, giá thấp, giá trung bình, số lượng giao dịch, doanh thu, số lượng giao dịch, số lượng có thể giao và tỷ lệ giao dịch so với tỷ lệ phần trăm. Những điều này được trình bày thuận tiện dưới dạng danh sách từ điển.

Phiên bản Python 3.X với các yêu cầu và 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)

Bên cạnh đó, đoạn mã này tương đối mô-đun và sẵn sàng để sử dụng.


Cảm ơn anh bạn! này làm việc cho tôi thay vì câu trả lời trên từ @andrean
Nitish Kumar Pal

Xin chào, tôi thực sự không biết phải đập đầu vào đâu nữa, tôi đã thử giải pháp này và nhiều giải pháp khác nữa nhưng tôi tiếp tục gặp lỗi 403. Tôi có thể thử thêm cách nào khác không?
Francesco

Trạng thái 403 nhằm thông báo rằng trình duyệt của bạn không được xác thực để sử dụng dịch vụ này. Có thể trong trường hợp của bạn, nó thực sự yêu cầu xác thực với auth cơ bản, oauth, v.v.
Supreet Sethi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.