HOWTO · Python

Python에서 Urllib HTTP 오류 403 금지 메시지 해결

이 자습서에서는 urllib 모듈을 사용할 때 HTTP 오류 403 금지 메시지를 방지하는 방법을 설명합니다.

이 페이지의 내용

오늘의 기사에서는 금지된 리소스에 직면할 때 request 클래스를 대신하여 error 클래스에서 생성된 urllib.error.HTTPError: HTTP 오류 403: 금지됨 오류 메시지(예외)를 처리하는 방법에 대해 설명합니다.

Python의 urllib 모듈

urllibPython 모듈은 다른 프로토콜을 통해 Python용 URL을 처리합니다. 특정 웹 사이트에서 데이터를 얻으려는 웹 스크래퍼로 유명합니다.

urllib에는 읽기, URL 구문 분석 및 robots.txt와 같은 특정 작업을 수행하는 클래스, 메서드 및 함수가 포함되어 있습니다. request, error, parserobotparser의 네 가지 클래스가 있습니다.

urllib HTTP 오류 403 금지 메시지를 방지하려면 robots.txt를 확인하십시오.

urllib 모듈을 사용하여 request 클래스를 통해 클라이언트 또는 서버와 상호 작용할 때 특정 오류가 발생할 수 있습니다. 이러한 오류 중 하나는 HTTP 403 오류입니다.

URL을 읽는 동안 urllib 패키지에 urllib.error.HTTPError: HTTP 오류 403: 금지됨 오류 메시지가 나타납니다. 금지된 오류인 HTTP 403은 클라이언트 또는 서버가 요청된 리소스에 대한 액세스를 금지함을 나타내는 HTTP 상태 코드입니다.

따라서 urllib.error.HTTPError: HTTP 오류 403: 금지됨과 같은 오류 메시지가 표시되면 서버는 요청을 이해하지만 우리가 보낸 요청을 처리하거나 승인하지 않기로 결정합니다.

우리가 접속하는 웹사이트가 요청을 처리하지 않는 이유를 이해하려면 robots.txt라는 중요한 파일을 확인해야 합니다. 웹 스크래핑 또는 웹 사이트와 상호 작용하기 전에 이 파일을 검토하여 예상되는 사항을 파악하고 추가 문제에 직면하지 않는 것이 좋습니다.

모든 웹사이트에서 확인하려면 아래 형식을 따를 수 있습니다.

https://<website.com>/robots.txt

예를 들어 YouTube, Amazon 및 Google robots.txt 파일을 확인하십시오.

https://www.youtube.com/robots.txt
https://www.amazon.com/robots.txt
https://www.google.com/robots.txt

YouTube robots.txt를 확인하면 다음과 같은 결과가 나타납니다.

# robots.txt file for YouTube
# Created in the distant future (the year 2000) after
# the robotic uprising of the mid-'90s wiped out all humans.

User-agent: Mediapartners-Google*
Disallow:

User-agent: *
Disallow: /channel/*/community
Disallow: /comment
Disallow: /get_video
Disallow: /get_video_info
Disallow: /get_midroll_info
Disallow: /live_chat
Disallow: /login
Disallow: /results
Disallow: /signup
Disallow: /t/terms
Disallow: /timedtext_video
Disallow: /user/*/community
Disallow: /verify_age
Disallow: /watch_ajax
Disallow: /watch_fragments_ajax
Disallow: /watch_popup
Disallow: /watch_queue_ajax

Sitemap: https://www.youtube.com/sitemaps/sitemap.xml
Sitemap: https://www.youtube.com/product/sitemap.xml

거기에서 많은 Disallow 태그를 볼 수 있습니다. 이 Disallow 태그는 액세스할 수 없는 웹 사이트 영역을 표시합니다. 따라서 해당 영역에 대한 요청은 처리되지 않으며 금지됩니다.

다른 robots.txt 파일에는 허용 태그가 표시될 수 있습니다. 예를 들어 http://youtube.com/commenturllib 모듈을 사용하는 경우에도 모든 외부 요청에 대해 금지됩니다.

액세스할 때 HTTP 403 오류를 반환하는 웹 사이트에서 데이터를 스크랩하는 코드를 작성해 보겠습니다.

예제 코드:

import urllib.request
import re

webpage = urllib.request.urlopen(
    "https://www.cmegroup.com/markets/products.html?redirect=/trading/products/#cleared=Options&sortField=oi"
).read()
findrows = re.compile('<tr class="- banding(?:On|Off)>(.*?)</tr>')
findlink = re.compile('<a href =">(.*)</a>')

row_array = re.findall(findrows, webpage)
links = re.findall(findlink, webpage)

print(len(row_array))

출력:

Traceback (most recent call last):
  File "c:\Users\akinl\Documents\Python\index.py", line 7, in <module>
    webpage = urllib.request.urlopen('https://www.cmegroup.com/markets/products.html?redirect=/trading/products/#cleared=Options&sortField=oi').read()
  File "C:\Python310\lib\urllib\request.py", line 216, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python310\lib\urllib\request.py", line 525, in open
    response = meth(req, response)
  File "C:\Python310\lib\urllib\request.py", line 634, in http_response
    response = self.parent.error(
  File "C:\Python310\lib\urllib\request.py", line 563, in error
    return self._call_chain(*args)
  File "C:\Python310\lib\urllib\request.py", line 496, in _call_chain
    result = func(*args)
  File "C:\Python310\lib\urllib\request.py", line 643, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

그 이유는 우리가 웹 사이트에 액세스하는 것이 금지되어 있기 때문입니다. 그러나 robots.txt 파일을 확인하면 https://www.cmegroup.com/markets/Disallow 태그가 없음을 알 수 있습니다. 그러나 스크랩하려는 웹 사이트의 robots.txt 파일을 아래로 이동하면 다음을 찾을 수 있습니다.

User-agent: Python-urllib/1.17
Disallow: /

위의 텍스트는 Python-urllib라는 사용자 에이전트가 사이트 내의 URL을 크롤링할 수 없음을 의미합니다. 즉, Python urllib 모듈을 사용하여 사이트를 크롤링할 수 없습니다.

따라서 robots.txt를 확인하거나 구문 분석하여 어떤 리소스에 액세스할 수 있는지 알아보세요. robotparser 클래스를 사용하여 robots.txt 파일을 구문 분석할 수 있습니다. 이를 통해 코드에서 urllib.error.HTTPError: HTTP 오류 403: 금지됨 오류 메시지가 발생하지 않도록 할 수 있습니다.

urllib HTTP 오류 403 금지 메시지를 해결하기 위해 요청 헤더에 쿠키 추가

유효한 사용자 에이전트를 헤더 매개변수로 전달하면 문제가 빠르게 해결됩니다. 웹사이트는 스크래핑 방지 수단으로 쿠키를 사용할 수 있습니다.

웹 사이트는 정책에 위배되는 스크래핑을 방지하기 위해 쿠키를 다시 에코하도록 설정하고 요청할 수 있습니다.

from urllib.request import Request, urlopen


def get_page_content(url, head):

    req = Request(url, headers=head)
    return urlopen(req)


url = "https://example.com"
head = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    "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",
    "refere": "https://example.com",
    "cookie": """your cookie value ( you can get that from your web page) """,
}

data = get_page_content(url, head).read()
print(data)

출력:

<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta
'
'
'
<p><a href="https://www.iana.org/domains/example">More information...</a></p>\n</div>\n</body>\n</html>\n'

유효한 사용자 에이전트를 헤더 매개변수로 전달하면 문제가 빠르게 해결됩니다.

세션 개체를 사용하여 urllib HTTP 오류 403 금지 메시지 해결

경우에 따라 사용자 에이전트를 사용해도 이 오류가 발생하는 것을 막을 수 없습니다. 그런 다음 requests 모듈의 Session 개체를 사용할 수 있습니다.

from random import seed
import requests

url = "https://stackoverflow.com/search?q=html+error+403"
session_obj = requests.Session()
response = session_obj.get(url, headers={"User-Agent": "Mozilla/5.0"})

print(response.status_code)

출력:

200

위의 글에서는 urllib.error.HTTPError: HTTP Error 403: Forbidden의 원인과 이에 대한 해결 방법을 찾습니다. mod_security는 기본적으로 서로 다른 웹 페이지가 인간과 자동화된 컴퓨터(봇)를 구별하기 위해 서로 다른 보안 메커니즘을 사용하기 때문에 이 오류를 발생시킵니다.