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.