광고 차단 프로그램이 감지되었습니다

이 사이트는 광고 수익을 통해 무료로 콘텐츠와 서비스를 제공하고 있습니다.

더 나은 서비스를 위해 광고 차단 프로그램을 비활성화 해주세요.

광고 차단 해제 방법 보기
Loading...

비동기 크롤링 보고서

비동기 크롤링 보고서에 대한 img

비동기 크롤링 보고서에 대한 img

📚 웹 스크레이핑 문제 해결 (403 오류 및 데이터 누락) 마스터 청사진


💡 상황 해독

  • 현재 상태: 웹사이트에서 필요한 정보(배우 이름, 이메일, 인스타그램 주소 등)를 자동으로 싹 긁어오려고 파이썬 코드를 만들었어요. 그런데 자꾸 웹사이트가 "너 들어오지 마!" 하고 막거나(403 Forbidden 오류), 분명히 웹사이트에는 정보가 있는데도 코드가 정보를 못 찾고 빈칸으로 가져오는 일이 생기고 있습니다. 신기하게도 그냥 인터넷 창(브라우저)으로 보면 다 잘 보이는데, 제 코드만 실행하면 말썽이네요.
  • 핵심 쟁점:
  • 만든 프로그램(스크립트)이 웹사이트 서버로부터 접근 거부당함 (403 오류).
  • 웹페이지마다 생김새(HTML 구조)가 조금씩 달라서, 원하는 정보(특히 이름, 인스타그램)를 놓침.
  • 데이터 긁어오는 데 시간이 너무 오래 걸림 (특히 많은 페이지를 처리할 때).
  • 예상 vs 현실: 코드로 돌리면 클릭 몇 번보다 훨씬 빠르고 편하게 데이터가 모일 줄 알았는데, 실제로는 오류 때문에 자꾸 멈추고 빠진 데이터 메꾸느라 오히려 더 귀찮고 시간이 걸리는 상황입니다.
  • 영향 범위: 원하는 배우 정보를 제때 못 모으게 되고, 문제 해결하느라 시간만 버리고 스트레스받습니다. 만약 웹사이트가 내 컴퓨터(IP 주소)를 완전히 차단하면, 앞으로 그 사이트 접속 자체가 어려워질 수도 있습니다.


🔍 원인 투시

  • 근본 원인: 웹사이트 주인 입장에서는 정상적인 방문객(사람)들이 서비스를 잘 이용하는 게 중요하지, 정체 모를 로봇(스크립트)이 와서 순식간에 정보를 대량으로 퍼가는 걸 좋아하지 않아요. 그래서 "어? 얘는 사람 아닌 것 같은데?" 싶으면 문을 잠그거나(접근 차단), 내부 구조를 살짝 바꿔서 로봇이 헤매게 만듭니다.
  • 연결 고리:
  • (원인) 너무 빠르게 접속하거나, 요청 정보가 부실해서 사람처럼 안 보임 → (결과) 서버가 "너 로봇이지?" 의심 → 접근 차단 (403 오류 발생).
  • (원인) 웹사이트 디자인이 바뀌거나, 페이지마다 정보 배치 방식이 조금씩 다름 → (결과) "여기서 이름 찾아와!" 하고 고정된 위치만 보도록 만든 코드가 헤맴 → 정보 못 찾고 누락됨.
  • 일상 비유:
  • 비유 1 (403 오류): 내가 만든 로봇을 시켜서 인기 빵집에 1초마다 가서 빵 100개씩 사 오라고 시키는 거예요. 빵집 주인은 로봇이 수상하기도 하고 다른 손님들한테 피해가 가니까 "더 이상 안 팔아!" 하고 로봇을 쫓아내는 거죠.
  • 비유 2 (데이터 누락): 친구 집 주소를 'OO 아파트 101동 101호'로 외우고 찾아갔는데, 가보니 친구가 'OO 빌라 가동 101호'로 이사 갔거나, 어떤 집은 'A동'이라고 써 붙여놨어요. 내가 외운 주소랑 다르니 친구 집을 못 찾는 거죠.
  • 비유 3 (자동화 패턴 감지): 매일 새벽 3시에 똑같은 옷을 입고 편의점에 가서 특정 음료수만 싹 쓸어가는 손님이 있다고 상상해보세요. 편의점 주인은 뭔가 이상하다고 느끼고 그 손님에게는 물건을 안 팔려고 할 수 있겠죠. 내 스크립트도 너무 티 나게 행동하면 서버가 감지하고 막는 거예요.
  • 숨겨진 요소: 웹사이트는 그냥 화면만 보여주는 게 아니라, 접속하는 컴퓨터가 남기는 여러 흔적(IP 주소, 어떤 종류의 브라우저/운영체제인지 알리는 정보(User-Agent), 로그인 상태 정보(쿠키), 얼마나 자주 접속하는지 등)을 보고 사람인지 로봇인지 나름대로 판단하고 있어요. 그리고 모든 배우 프로필 페이지가 완전히 똑같은 디자인 틀을 사용하지 않을 수도 있다는 점도 중요해요.


🛠️ 해결 설계도

  1. 사람인 척 위장하기 (403 오류 피하기)
  • 핵심 행동: 내 프로그램이 웹사이트에 접속할 때, 최대한 '진짜 사람'이 '일반적인 웹 브라우저'로 접속한 것처럼 보이게 꾸민다.
  • 실행 가이드:
  1. 내가 쓰는 웹 브라우저(크롬, 엣지 등)의 '신분증' 정보(User-Agent 값)를 알아내서, 내 코드가 웹사이트에 요청 보낼 때 같이 보낸다. (개발자 도구 Network 탭에서 확인 가능)
  2. 로그인이 필요한 사이트라면, 먼저 브라우저로 로그인한 뒤, 개발자 도구(Application 또는 Storage 탭)에서 '쿠키(Cookie)' 값을 복사해서 내 코드에 넣어준다. (로그인 상태 유지)
  3. 너무 빠르게 요청하지 않도록 코드 중간에 잠깐 쉬는 시간(time.sleep)을 주거나, 동시에 너무 많은 요청을 보내지 않도록 조절한다(asyncio.Semaphore 사용).
  • 성공 지표: 이전보다 403 Forbidden 오류가 눈에 띄게 줄어든다.
  • 예시/코드 (3.py 또는 4.py 참고):
# 변경 전 (기본, 아무 정보 없음)
# response = httpx.get(url) 

# 변경 후 (사람 흉내내기)
cookies = { 
    'PHPSESSID': '최신값...', 
    'rx_login_status': '최신값...', 
    # ... (로그인 관련 쿠키들)
}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)...', # 내 브라우저 정보
    'Accept-Language': 'ko,en;q=0.9...', 
    # ... (다른 헤더들)
}

# 비동기 클라이언트에 쿠키와 헤더 설정
async with httpx.AsyncClient(cookies=cookies, headers=headers) as client:
    response = await client.get(url)

# 핵심 변화 설명: 웹사이트에 접속할 때, '나 이런 브라우저 쓰는 사람이야'(User-Agent)라는 명찰과 '나 로그인한 회원이야'(Cookie)라는 출입증을 보여주는 것과 같음.
  • 주의사항: 쿠키 값은 시간이 지나면 무효가 되니, 오류가 나면 최신 값으로 바꿔줘야 함. User-Agent도 너무 옛날 브라우저 정보면 이상하게 보일 수 있음.
  1. 정보 탐정처럼 찾기 (데이터 누락 줄이기)
  • 핵심 행동: 웹페이지 구조가 조금씩 달라도 원하는 정보를 찾을 수 있도록, 한 가지 방법이 실패하면 다른 방법으로 찾는 '플랜 B'를 준비한다.
  • 실행 가이드:
  1. 가장 확실해 보이는 방법(예: 아주 구체적인 CSS 선택자)으로 정보를 먼저 찾아본다.
  2. 만약 못 찾으면, 좀 더 넓은 범위나 다른 특징(예: '홈페이지'라는 글자 옆, 특정 영역 안의 첫 번째 제목 태그 h2)을 이용해서 다시 찾아본다.
  3. 이름이나 링크 주소처럼 특정 패턴이 있는 정보는 정규 표현식(RegEx)으로 텍스트 안에서 찾아본다. (단, HTML 구조를 무시하고 찾으므로 엉뚱한 걸 찾을 수도 있음)
  4. 찾아낸 정보가 지저분하면(예: 이름 뒤에 "(클릭)" 같은 글자가 붙음, 인스타 링크에 embed.js 같은 불필요한 게 섞임) 깔끔하게 다듬는 후처리 작업을 한다. 중복된 정보는 제거한다.
  • 성공 지표: 전에는 비어있던 이름이나 인스타그램 칸에 데이터가 채워지는 경우가 늘어난다.
  • 예시/코드 (3.py 또는 4.py의 extract_name...extract_instagram... 함수 참고):
# 변경 전 (한 가지 방법만 고집)
# name_element = soup.select_one('#아주_구체적인_선택자')
# name = name_element.get_text() if name_element else None

# 변경 후 (여러 방법 시도 + 후처리)
async def extract_name_from_profile_page(html_content: str):
    # ... (BeautifulSoup 준비) ...
    name = None

    # 방법 1: 구체적 선택자 시도
    name_element = soup.select_one('#board_content ... h2 > a') 
    if name_element: name = name_element.get_text(strip=True)

    # 방법 2: 실패 시 다른 방법 (h2 태그 찾기)
    if not name:
        board_content = soup.select_one('#board_content > div.board')
        if board_content:
            h2_element = board_content.find('h2')
            if h2_element: name = h2_element.get_text(strip=True)

    # 방법 3: 후처리 (괄호 내용 제거)
    if name and "(" in name: name = name.split('(').strip()
    
    return name

# 핵심 변화 설명: 첫 번째 수색 방법(구체적 주소)이 실패하면, 두 번째 수색 방법(근처 큰 건물 찾기)을 쓰고, 찾은 정보도 깔끔하게 정리해서 최종 결과를 만듦.
  • 주의사항: 아무리 여러 방법을 써도 정보 자체가 페이지에 없거나, 예상과 너무 다른 방식으로 숨겨져 있으면 못 찾을 수도 있음. 100% 완벽한 추출은 목표가 아닐 수 있음.
  1. 똑똑하게 작업 관리하기 (속도 개선 및 안정성 확보)
  • 핵심 행동: 컴퓨터가 웹사이트 응답을 기다리며 노는 시간을 줄여서 작업 속도를 높이고, 중간에 멈추더라도 처음부터 다시 시작하지 않도록 한다. 동시에 웹사이트에 너무 피해를 주지 않도록 속도를 조절한다.
  • 실행 가이드:
  1. 한 번에 하나씩 순서대로 처리하는 동기 방식 대신, 여러 작업을 동시에 처리하는 비동기 방식(asynciohttpx)을 사용한다.
  2. 컴퓨터와 웹사이트 서버에 무리가 가지 않도록, 동시에 진행할 작업의 최대 개수(asyncio.Semaphore)를 적절히 설정한다. (너무 많으면 서버가 화내고, 너무 적으면 느림)
  3. 작업 중간 결과를 계속 파일에 저장한다. 예를 들어, 찾아낸 프로필 URL 목록(collected_profile_urls.txt)과 이미 처리한 결과(actors_data.csv)를 기록해두고, 프로그램이 다시 시작될 때 이 파일들을 읽어서 어디까지 작업했는지 확인하고 다음 작업부터 이어서 한다.
  • 성공 지표: 수천 개의 프로필을 처리하는 시간이 이전보다 훨씬 단축된다. 실수로 프로그램을 껐다 켜도 처음부터 다시 시작할 필요가 없다.
  • 예시/코드: (3.py 또는 4.py의 async def main...load_...save_... 함수들 참고)
  • 주의사항: 비동기 코드는 일반적인 순차 코드보다 조금 더 복잡하게 느껴질 수 있음. 동시 작업 개수를 너무 높게 잡으면 '사람인 척'하려는 노력이 무색하게 서버에 차단될 수 있음.


🧠 핵심 개념 해부

  • 웹 스크레이핑 (Web Scraping): 일상적 재정의
  • 5살에게 설명한다면: 인터넷이라는 큰 그림책에서 내가 원하는 그림(정보)만 골라서 내 스케치북(파일)에 자동으로 베껴 그리는 거야.
  • 실생활 예시: 여러 항공사의 비행기 표 가격을 한눈에 비교해주는 사이트, 특정 연예인 관련 뉴스 기사만 매일 아침 모아서 보여주는 앱.
  • 숨겨진 중요성: 단순 반복 작업을 컴퓨터에게 맡겨 내 시간을 아낄 수 있고, 사람이 일일이 보기 힘든 엄청난 양의 정보 속에서 패턴이나 의미를 찾아낼 수 있게 해줘.
  • 오해와 진실: (오해) 모든 웹사이트는 긁어도 괜찮다. -> (진실) 웹사이트마다 주인이 정한 규칙(robots.txt, 이용 약관)이 있고, 함부로 긁으면 경고를 받거나 법적인 문제가 생길 수도 있어. / (오해) 한 번 만들어두면 평생 쓸 수 있다. -> (진실) 웹사이트는 수시로 디자인이나 구조가 바뀌기 때문에, 내 스크레이핑 코드도 계속 고쳐줘야 해.
  • HTTP 요청/응답 (HTTP Request/Response): 일상적 재정의
  • 5살에게 설명한다면: 내가 식당(웹사이트)에 가서 "메뉴판 보여주세요!"(요청)라고 말하면, 점원이 "네, 여기 있습니다."(응답) 하면서 메뉴판(웹페이지)을 가져다주는 것과 같아.
  • 실생활 예시: 인터넷 주소창에 naver.com 치고 엔터(요청), 네이버 화면이 보이는 것(응답). 쇼핑몰에서 '구매하기' 버튼 클릭(요청), '주문 완료' 페이지가 뜨는 것(응답).
  • 숨겨진 중요성: 내가 어떻게 요청하느냐(예: 로그인 정보 포함 여부)에 따라 웹사이트가 다른 응답(로그인된 화면, 에러 화면)을 줄 수 있어. 응답할 때 같이 오는 숫자 코드(200: 성공, 403: 접근 금지, 404: 없음 등)는 내 요청이 어땠는지 알려주는 중요한 신호야.
  • 오해와 진실: (오해) 인터넷 접속은 다 똑같다. -> (진실) 요청에는 여러 종류(GET: 정보 보기, POST: 정보 제출 등)가 있고, 요청에 어떤 '짐'(헤더, 쿠키, 데이터)을 실어 보내느냐에 따라 결과가 달라져.
  • HTML & CSS 선택자 (HTML & CSS Selectors): 일상적 재정의
  • 5살에게 설명한다면: 웹페이지라는 커다란 장난감 상자(HTML)에서, 내가 딱 원하는 '빨간색 로봇 장난감'(정보)을 찾기 위한 '꼬리표'(CSS 선택자) 같은 거야. "상자 오른쪽 구석에 있는 세 번째 칸의 빨간 로봇!" 이렇게.
  • 실생활 예시: 블로그 글에서 '작성자 이름' 부분 찾기, 쇼핑몰 페이지에서 '상품 가격' 숫자만 콕 집어내기.
  • 숨겨진 중요성: 웹사이트 주인이 장난감 상자 정리를 다시 하면(HTML 구조 변경), 내가 붙여둔 꼬리표가 엉뚱한 걸 가리킬 수 있어. 너무 자세한 꼬리표보다는 좀 더 넓은 의미의 꼬리표(예: '로봇 장난감 칸')를 쓰는 게 더 오래갈 수 있어.
  • 오해와 진실: (오해) 브라우저 개발자 도구가 알려주는 선택자 주소는 무조건 정답이다. -> (진실) 개발자 도구가 알려주는 주소는 너무 길고 복잡해서, 상자 정리(HTML 변경)에 매우 취약할 수 있어. 직접 보고 더 간단하고 핵심적인 주소를 찾는 연습이 필요해.
  • 비동기 처리 (Asynchronous Processing): 일상적 재정의
  • 5살에게 설명한다면: 숙제(작업)를 하는데, 수학 문제(네트워크 요청) 풀다가 답 기다리는 동안 국어 숙제(다른 작업) 먼저 하고, 답 오면 다시 수학 숙제하는 거야. 한 문제 답 기다리느라 멍하니 있지 않으니 숙제가 빨리 끝나!
  • 실생활 예시: 여러 개의 큰 파일을 동시에 다운로드 걸어두는 것, 유튜브 영상 보면서 댓글을 스크롤해서 보는 것 (영상 재생과 댓글 로딩이 동시에 진행).
  • 숨겨진 중요성: 특히 인터넷에서 정보를 기다리는 시간이 긴 작업(웹 스크레이핑, 파일 다운로드)에서 효과 만점이야. 컴퓨터가 노는 시간을 확 줄여줘. 하지만 코드 짜는 방식이 순서대로 하는 것보다 좀 더 복잡해질 수 있어.
  • 오해와 진실: (오해) 비동기는 마법처럼 모든 걸 빠르게 한다. -> (진실) 컴퓨터 내부 계산만 잔뜩 하는 작업은 비동기로 해도 별로 안 빨라져. 뭔가를 '기다리는' 시간이 많은 종류의 작업에서 효과를 발휘해.


🔮 미래 전략 및 지혜

  • 예방 전략:
  1. 긁기 전에 예의 지키기: 스크레이핑하려는 웹사이트의 robots.txt 파일(보통 웹사이트주소/robots.txt)을 확인해서 '긁지 말라'는 부분은 피하고, 웹사이트 이용 약관에 자동 수집 금지 조항이 있는지 살펴본다.
  2. '착한 로봇' 되기: 요청 사이에 반드시 쉬는 시간(time.sleep 또는 비동기 제어)을 넣고, '나 사람이에요'라고 알리는 User-Agent 헤더를 꼭 포함한다. 동시 요청 수는 최소한으로 유지한다.
  3. 실패에 대비하기: 정보를 찾는 코드는 항상 실패할 수 있다고 가정하고, '플랜 B' (다른 선택자, 다른 방식)를 준비하거나, 못 찾았을 때 어떻게 처리할지(예: 빈 값 저장, 로그 남기기) 미리 정해둔다. 오류 처리(try-except)는 필수!
  • 장기적 고려사항: 웹사이트는 살아있는 생물처럼 계속 변한다는 것을 기억해야 한다. 오늘 잘 되던 코드도 내일은 오류를 낼 수 있으니, 꾸준한 관심과 유지보수가 필요하다. 무분별한 스크레이핑은 법적 문제나 서비스 차단으로 이어질 수 있으니 항상 책임감을 가져야 한다.
  • 전문가 사고방식: "어떻게 하면 안 들키고 최대한 많이, 빨리 긁어올까?"가 아니라, "어떻게 하면 웹사이트에 피해를 주지 않으면서, 오랫동안 안정적으로 필요한 데이터를 얻을 수 있을까?"를 고민한다. 단순히 코드를 짜는 것을 넘어, 웹 기술과 데이터 윤리에 대한 이해를 넓히려 노력한다.
  • 학습 로드맵:
  1. 기초 다지기: 파이썬 기본 문법 마스터하기.
  2. 문 열기requests (동기) 또는 httpx (동기/비동기) 라이브러리로 웹 페이지 내용 가져오기 연습.
  3. 지도 읽기: HTML과 CSS가 웹 페이지를 어떻게 구성하는지 기본 원리 이해하기 (태그, 속성, 구조).
  4. 보물찾기 도구BeautifulSoup 라이브러리로 HTML 속에서 원하는 정보(텍스트, 링크) 찾아내기 연습 (CSS 선택자 활용).
  5. 패턴 인식: 정규 표현식(RegEx)으로 복잡한 텍스트 속에서 이메일, 전화번호 등 특정 패턴 찾아내기 연습.
  6. (선택) 속도 향상asyncio와 httpx로 비동기 스크레이핑 구현해보기 (효율 증대).
  7. (선택) 전문 장비Scrapy 같은 전문 스크레이핑 프레임워크 사용법 익히기 (대규모 작업).
  8. (고급) 난관 극복: JavaScript로 동적으로 변하는 웹사이트 긁는 법 배우기 (Selenium 등 브라우저 자동화 도구 활용).


🌟 실전 적용 청사진

  • 즉시 적용:
  1. 지금 만들고 있는 스크레이핑 코드에 headers={'User-Agent': '내 브라우저 정보'} 추가하기.
  2. 정보를 찾을 때 try-except 구문으로 감싸서 오류가 나도 프로그램이 멈추지 않게 하기.
  3. 반복문 안에 time.sleep(0.5) 같은 코드를 넣어 최소한의 요청 간격 두기 (0.5초).
  • 중기 프로젝트: 내가 자주 방문하는 웹사이트(단, 너무 복잡하지 않은 곳) 하나를 정해서, 첫 3페이지 정도의 특정 정보(예: 게시글 제목과 작성자, 상품 이름과 가격)를 자동으로 수집해서 CSV 파일로 저장하는 나만의 스크레이퍼 만들어보기. (403 오류, 데이터 누락 등 발생 시 해결 시도 포함)
  • 숙련도 점검:
  • 로그인해야만 볼 수 있는 페이지의 정보를 긁어올 수 있는가? (쿠키/세션 처리)
  • 클릭해야 내용이 나타나는 페이지(JavaScript 사용)의 정보를 긁어올 수 있는가?
  • 웹사이트에서 IP 차단을 시도할 때, 이를 우회하는 방법(예: 프록시 서버)을 알고 시도해볼 수 있는가? (주의: 기술적/윤리적 고려 필요)
  • 긁어온 데이터를 단순히 저장하는 것을 넘어, 내가 원하는 형태로 가공하거나 분석할 수 있는가? (pandas 라이브러리 활용 등)
  • 추가 리소스:
  • (입문) 생활코딩 WEB2 - Python: https://opentutorials.org/course/3131 (파이썬으로 웹 다루기 기초)
  • (초급) 점프 투 파이썬 - 웹 프로그래밍: https://wikidocs.net/book/1 (책 후반부 웹 관련 내용)
  • (초중급) BeautifulSoup 공식 문서 (한글 번역도 있음): https://www.crummy.com/software/BeautifulSoup/bs4/doc.ko/
  • (중급) 파이썬 공식 asyncio 문서: https://docs.python.org/ko/3/library/asyncio.html
  • (고급) Scrapy 튜토리얼: https://docs.scrapy.org/en/latest/intro/tutorial.html
  • (실전) 구글에서 'python web scraping tutorial', 'python beautifulsoup examples', 'python httpx async example', '웹 크롤링 윤리' 등 검색


📝 지식 압축 요약

  • 웹 스크레이핑 시 403 오류는 '로봇 의심' 때문이니, 최대한 '사람인 척'(헤더/쿠키 설정, 속도 조절)해서 접근해야 뚫릴 가능성이 높다.
  • 페이지마다 생김새가 다르므로, 데이터 추출은 한 가지 방법만 고집하지 말고 여러 선택지와 후처리, 정규식을 동원해 유연하게 탐색해야 놓치는 정보를 줄일 수 있다.
  • 느린 네트워크 작업을 효율화하려면 비동기 처리가 강력하지만, 서버 차단을 피하려면 동시 요청 수를 현명하게 조절하고, 장시간 작업 시에는 이어하기 기능을 구현하는 것이 필수다.
  • 성공적인 스크레이핑은 단순히 코딩 기술을 넘어, 웹사이트를 존중하는 '착한 로봇'의 자세와 끊임없이 변화에 적응하는 유지보수 노력이 중요하다.

 

목차
목차를 불러오는 중...

댓글

Loading...

댓글 로딩 중...

구글 검색