urllib2.HTTPError : HTTP 오류 403 : 금지됨


102

파이썬을 사용하여 역사적인 주식 데이터 다운로드를 자동화하려고합니다. 열려고하는 URL이 CSV 파일로 응답하지만 urllib2를 사용하여 열 수 없습니다. 나는 이전에 몇 가지 질문에 명시된대로 사용자 에이전트를 변경하려고 시도했으며, 운이없이 응답 쿠키를 허용하려고 시도했습니다. 도와 주 시겠어요?

참고 : 동일한 방법이 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 (), code, 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
신분 : www.nseindia.com 수락 - 인코딩 : 가까운 호스트 : 와이어 샤크는 만 사용자 에이전트는 연결과 함께 보냈습니다 보여 주었다
— andrean

1
천만에요. 제가 실제로 한 일은 브라우저에서 스크립트의 URL을 확인한 후 거기에서 작동하는 동안 브라우저가 보낸 모든 요청 헤더를 복사하여 여기에 추가했는데 그게 해결책이었습니다.
— andrean 2012

1
@Mee 아래 답변을 보셨습니까? 그것은 ... 당신을 위해 작동하는 경우, 파이썬 3을 위해 특별히 검사를 해결했다
— andrean

1
내 대답의 다른 헤더도 요청에 추가하십시오. 여전히 서버가 403을 반환하는 다른 많은 이유가 있습니다. 주제에 대한 다른 답변도 확인하십시오. 대상에 관해서는, Google은 특히 긁 히기 어렵고 스크래핑을 방지하기 위해 많은 방법을 구현했습니다.
— 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
일부 사이트 (위키 백과 포함)는 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에서 위의 대답 대신 나를 위해 일한
— 니티시 쿠마르 래에게

안녕하세요, 저는 더 이상 내 머리를 어디로 쳐야할지 모르겠습니다.이 솔루션을 비롯한 여러 가지 방법을 시도했지만 계속 오류 403이 발생합니다. 다른 시도가 있습니까?
— Francesco

403 상태는 브라우저가이 서비스를 사용하도록 인증되지 않았 음을 알리기위한 것입니다. 그것은 귀하의 경우, 그것은 진정으로 기본 인증과 인증, OAuth를 등을 필요로 할 수있다
— Supreet 세티
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.