티스토리 뷰

728x90
반응형

개요

파이썬에서 웹 크롤러를 만들 때 가장 큰 어려움은 역시 웹 사이트에서의 크롤러 또는 자동화 도구의 차단인 것 같습니다. 이런 경우 보통 time.sleep(3) 과 같이 몇 초간 크롤러를 쉬도록 하는데, 최근에 나오는 웹 사이트들을 차단 방법들이 더 다양해져서 이제는 동일한 기기에서 짧은 시간동안 여러 요청을 했을 경우에 차단하기도 합니다.

 

물론 동일한 기기를 판단하는 기준이 IP주소라면 별로 할 말이 없지만, IP주소가 아닌 User-Agent 값이라면 차단 우회 방법으로 User-Agent 값을 수시로 변경해주는 것으로 생각할 수 있습니다.

 

사실 크롤러에서 User-Agent 값은 일정한 데이터를 웹사이트로부터 응답받기 위해서 사용되는 중요한 요소입니다. 예를 들어 어떤 웹사이트의 경우 반응형으로 디자인 되어, 모바일의 경우 또는 데스크톱의 경우를 나누어서 클라이언트 사이드 소스코드가 달라집니다. 해서 크롤링 시 이런 기기 종류에 따른 변경사항들을 원천에 차단시키기 위해서 고정된 User-Agent 값을 사용해서 웹사이트의 소스코드를 가져오게 합니다.

 

파이썬에서는 requests 모듈로 GET 이나 POST 로 요청 시 headers 옵션의 User-Agent 값을 커스터마이징 하여 보내도록 합니다. 아래와 같이 말이죠.

import requests

url = 'https://domdom.tistory.com'
headers = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36'
}
response = requests.get(url, headers=headers)​

 

fake_useragent 모듈

인터넷에 파이썬 크롤링 시 user-agent 값 랜덤하게 변경과 관련된 검색어를 입력하여 찾아보면, 대부분 fake_useragent 라는 모듈을 설치하고 이를 사용하는 방법에 대해서 나옵니다.

  • fake_useragent 모듈 파이썬에서 설치하는 방법
pip install fake-useragent

 

 

  • fake_useragent 모듈 기본 사용법 예시
from fake_useragent import UserAgent
ua = UserAgent(verify_ssl=False)

ua.ie
# Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US);
ua.msie
# Mozilla/5.0 (compatible; MSIE 10.0; Macintosh; Intel Mac OS X 10_7_3; Trident/6.0)'
ua['Internet Explorer']
# Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .NET CLR 3.3.69573; WOW64; en-US)
ua.opera
# Opera/9.80 (X11; Linux i686; U; ru) Presto/2.8.131 Version/11.11
ua.chrome
# Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2'
ua.google
# Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.13 (KHTML, like Gecko) Chrome/24.0.1290.1 Safari/537.13
ua['google chrome']
# Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11
ua.firefox
# Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/16.0.1
ua.ff
# Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:15.0) Gecko/20100101 Firefox/15.0.1
ua.safari
# Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25

# and the best one, random via real world browser usage statistic
ua.random

 

그러나 최근에 fake-useragent 를 사용하면서 아래와 같은 오류가 발생하기 시작했습니다.

Error occurred during loading data. Trying to use cache server https://fake-useragent.herokuapp.com/browsers/0.1.11
Traceback (most recent call last):
  File "C:\Python39\lib\site-packages\fake_useragent\utils.py", line 154, in load
    for item in get_browsers(verify_ssl=verify_ssl):
  File "C:\Python39\lib\site-packages\fake_useragent\utils.py", line 99, in get_browsers
    html = html.split('<table class="w3-table-all notranslate">')[1]
IndexError: list index out of range

 

이 오류의 원인은 바로 useragentstring.com 이나 w3schools.com 에서 html 코드를 바꾸었거나 서버가 죽어서 생기는 문제입니다. fake-useragent 모듈은 위 사이트에서 user-agent 목록을 파싱해서 받아오는데 하필이면 지금 시점에서 페이지를 이루는 html 코드에 변경사항이 생겼던 것입니다.

 

인터넷에 찾아보면 이런 문제를 해결하기 위해서 직접 fake-useragent 모듈 패키지의 소스코드 파일 중 utils.py 의 코드 내용에서 w3-table-all notranslate 부분을 ws-table-all notraslate 로 변경하라고 하는 사람도 있는데, 이는 앞으로 계속 html 코드가 바뀔 수 있다는 가정하에 그렇게 좋지 못한 방법인 것 같았습니다.

 

그래서 이런 경우에 해결책으로 fake-useragent 측에서도 공식 문서에 해결법을 작성해두긴 했습니다. 아래와 같은 속성을 추가해서 사용하면 위와 같은 오류는 나지 않을 것입니다.

from fake_useragent import UserAgent

ua = UserAgent(use_cache_server=True)
ua.random

use_cache_server 옵션은 fake-useragent 모듈에서 w3schools.com 와 같은 사이트에서 실시간으로 파싱하지 말고, fake-useragent에서 사용하는 heroku 서버에 등록해둔 캐시를 가져다가 사용하라는 의미입니다. heroku 서버에 있는 캐시는 이전에 w3schools.com 에서 잘 가져오던 데이터를 저장하고 있기 때문에 일반적으로는 캐시를 사용해도 무방합니다.

 

자세한 내용은 https://github.com/hellysmile/fake-useragent 링크를 참고하시면 동일한 내용을 확인하실 수 있습니다.

 

GitHub - hellysmile/fake-useragent: up to date simple useragent faker with real world database

up to date simple useragent faker with real world database - GitHub - hellysmile/fake-useragent: up to date simple useragent faker with real world database

github.com

 

user-agent 모듈

fake-useragent 모듈의 업데이트 내역을 확인해보면 알겠지만, 제일 마지막 릴리즈된 내역이 0.1.11 로써 2018년도 10월이 마지막입니다. 무려 22년도인 지금으로부터 4년정도 지났습니다. 이렇게 뭔가 업데이트도 안되고 문제에 대해서 활발히 해결되서 수정되는 것처럼 보이지도 않아서 신뢰가 떨어져서 저는 대체할 수 있는 다른 모듈이 없을까 검색하다가 user-agent 라는 모듈을 알게되었습니다. (물론 이외에도 정말 다양한 User-Agent 관련 모듈이 계속 배포되고 있긴 합니다)

 

  • 우선 설치법은 아래와 같습니다.
pip install user-agent

 

  • 그리고 기본사용 방법은 아래와 같습니다.
from user_agent import generate_user_agent, generate_navigator

print(generate_user_agent(device_type='desktop'))
print(generate_user_agent(os='win', device_type='desktop'))
print(generate_user_agent(os=('mac', 'linux'), device_type='desktop'))

navigator = generate_navigator()
print(navigator)
print(navigator['platform'])

저는 desktop 에 해당하는 User-Agent 가 필요하여 위와 같이 사용하였고, 매번 사용할 때마다 반환되는 User-Agent 값이 달라짐을 알 수 있습니다. 

 

generate_user_agent 는 단순히 지정한 속성에 알맞은 user-agent 문자열을 반환하는 반면에 generate_navigator은 user-agent 객체(dictionary 타입)을 반환해줍니다. 객체의 key 값을 지정하여 알맞은 값을 추출해서 사용할 수도 있게 해줍니다.

 

자세한 내용은 https://github.com/lorien/user_agent 링크를 참고하시면 동일한 내용을 확인하실 수 있습니다.

 

GitHub - lorien/user_agent: Generator of User-Agent header

Generator of User-Agent header. Contribute to lorien/user_agent development by creating an account on GitHub.

github.com

 

 

- 끝 -

728x90
반응형
댓글