1. Anti-bot 기술: 누가 우리와 술래잡기를 하고 있을까?
오늘은 웹 스크레이핑의 가장 흥미롭고, 약간은 논란의 여지가 있는 주제인 봇 방어 우회와 CAPTCHA와의 싸움에 대해 이야기하자. 프로그래머의 삶에서 자주 그렇듯이, 어떤 교묘한 나사를 만나도 왼쪽 방향으로 돌릴 수 있는 너트가 있을 것이다. 그래서 이런 장애물들을 어떻게 해결할 수 있을지 확인해보자.
꼼수를 찾기 전에, 우리가 다루고 있는 것이 무엇인지 이해해보자. Anti-bot 기술은 사이트를 과도하고, 때로는 원치 않는 자동화 프로그램의 주목으로부터 보호하는 시스템이다. 다음은 흔히 사용되는 방법들이다:
- CAPTCHA: CAPTCHA는 Anti-bot 세계의 핵무기와도 같다. 목표는 사람의 참여가 필요한 작업을 사용자에게 제시하여 봇 요청을 걸러내는 것이다. 예를 들어, 택시 이미지 모두 선택하기 또는 흐릿한 글자 조합을 읽는 것 등이 있다.
- 행동 분석: 어떤 사이트는 사용자가 얼마나 빨리 폼을 작성하거나 페이지 요소와 상호작용하는지를 평가한다. 너무 빠르다면? 당신은 차단될 수 있다.
- 요청 지연 및 제한: 사이트가 당신이 사람이 아니라고 의심되면, 요청 사이의 지연 시간을 늘리거나 당신을 완전히 차단할 수 있다.
2. Anti-bot 우회 방법
이제 적의 정체를 알았으니, 이를 우회할 수 있는 몇 가지 방법을 살펴보자.
CAPTCHA 해결
가장 명확하면서도 어려운 방법은 CAPTCHA 해결 자동화이다. 가능은 하지만 특정 도구와 서드파티 서비스를 요구한다. CAPTCHA는 텍스트, 그래픽, 심지어 오디오 CAPTCHA와 같이 다양한 타입이 있다.
CAPTCHA를 자동으로 해결하려면 2Captcha 또는 Anti-Captcha 같은 API 서비스를 사용할 수 있으며, 적은 비용으로 해결할 수 있다. 다음은 이를 실제로 구현하는 방법의 예이다:
import requests
def solve_captcha(api_key, site_url, captcha_image_url):
# CAPTCHA 이미지 다운로드
captcha_image = requests.get(captcha_image_url).content
# 이미지 서비스를 전송하여 작업 ID를 받음
response = requests.post("http://2captcha.com/in.php", files={'file': captcha_image}, data={'key': api_key, 'method': 'post'})
captcha_id = response.text.split('|')[1]
# CAPTCHA 해답 가져오기
solution_url = f"http://2captcha.com/res.php?key={api_key}&action=get&id={captcha_id}"
solution_response = requests.get(solution_url)
while 'CAPCHA_NOT_READY' in solution_response.text:
solution_response = requests.get(solution_url)
return solution_response.text.split('|')[1]
# 함수 사용 예제
api_key = '당신의_2CAPTCHA_API_KEY'
site_url = 'https://example.com'
captcha_image_url = 'https://example.com/captcha_image'
captcha_solution = solve_captcha(api_key, site_url, captcha_image_url)
print("CAPTCHA 해답:", captcha_solution)
이 코드는 CAPTCHA 해결 요청을 어떻게 작성할 수 있는지 보여준다. 하지만, 복잡한 그래픽 문제나 사이트가 알고리즘을 자주 변경하는 경우에는 이러한 방법이 비효율적일 수 있다.
인간 행동 흉내내기
또 다른 속임수는 인간 행동을 흉내내는 것이다. 스크립트에 임의로 지연을 삽입하거나, user-agent를 변경하거나, 양방향 상호작용을 에뮬레이트하거나 Selenium을 사용해 마우스 움직임 같은 행동을 추가할 수 있다:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome()
driver.get('https://example.com')
# 마우스 움직임 에뮬레이션
actions = ActionChains(driver)
element = driver.find_element_by_id('button')
actions.move_to_element(element)
actions.perform()
# 자연스러운 상호작용을 위한 지연
time.sleep(2)
# 행동 실행
element.click()
Selenium에 대해선 다음 강의에서 더 자세히 알아보자.
동적 IP와 프록시 사용
요청을 보내는 IP 주소를 변경하려면 프록시 서버를 사용할 수도 있다. 이는 한 IP에서 나오는 요청 수 제한을 우회하는 데 도움이 될 수 있다. 이를 위해 Bright Data나 Smartproxy 같은 서비스가 제공된다.
import requests
proxy = {
"http": "http://123.456.789.012:8080",
"https": "http://123.456.789.012:8080",
}
response = requests.get('https://example.com', proxies=proxy)
print(response.content)
3. 중요한 주의사항
Anti-bot 우회 구현은 지식과 실험을 요구한다. 중요한 점은 모든 방법이 합법적이지 않다거나 사이트에서 환영받지 않을 수 있다는 것이다. 항상 "robots.txt"를 확인하고, 웹 스크레이핑의 예의를 지키며 서버 과부하를 피하자. 이는 법적 문제를 피할 뿐 아니라 타인의 노력을 존중하는 일이기도 하다.
절대 집에서 큰 규모의 파서를 실행하지 말자. 학습 목적으로 스크레이핑을 한다면 문제가 없겠지만, 당신의 스크립트가 동시에 몇 천 개의 요청을 보내면서 누군가의 서버를 마비시킨다면, 누군가 질문하려고 할 수도 있다. 그리고 그 질문에 답할 사람이 찾아올 것이다.
GO TO FULL VERSION