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)

错误

http_error_default中的文件“ C:\ Python27 \ lib \ urllib2.py”,第527行,引发HTTPError(req.get_full_url(),代码,msg,hdrs,fp)urllib2.HTTPError:HTTP错误403:禁止

谢谢你的协助


您是否使用Windows作为平台?
丹尼斯

Answers:


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:关闭,主机:www.nseindia.com,Accept-Encoding:身份
andrean 2012年

1
不客气,好吧,我真正要做的是,我在浏览器中检查了脚本的url,并且在该脚本中可以正常工作,我只是复制了浏览器发送的所有请求标头,并在此处添加了它们,这就是解决方案。
andrean 2012年

1
@Mee您是否看过下面的答案?它专门针对python 3解决,请检查它是否对您
有用

1
尝试将其他标头(来自我的答案)也添加到请求中。仍然有很多其他原因导致服务器可能返回403,还请查看有关该主题的其他答案。至于目标,谷歌尤其是一个艰难的,有点难以刮,他们已经实施了许多防止刮的方法。
andrean

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
确实,某些站点(包括Wikipedia)阻止了常见的非浏览器用户代理字符串,例如Python的库发送的“ Python-urllib / xy”。即使是普通的“ Mozilla”或“ Opera”通常也足以绕过它。当然,这并不适用于原始问题,但是知道它仍然很有用。
efotinis

7

NSE网站已更改,较旧的脚本是当前网站的半最佳状态。此摘要可以收集安全性的日常细节。详细信息包括代码,证券类型,先前收盘价,开盘价,高价,低价,平均价格,交易数量,营业额,交易数量,可交付数量以及已交付与交易的比率(百分比)。这些方便地以字典形式的列表形式呈现。

带有请求和BeautifulSoup的Python 3.X版本

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的答案
Nitish Kumar Pal,

嗨,我真的不知道该怎么敲我的头了,我已经尝试过这种解决方法,但是我仍然遇到错误403。还有其他可以尝试的方法吗?
Francesco

403状态旨在通知您的浏览器未通过身份验证以使用此服务。这可能是因为在你的情况下,真正需要使用基本身份验证的身份验证,OAuth的等等
Supreet塞西
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.