종원

인공지능 사관학교 - 2주차 (9일차, 웹크롤링) 본문

인공지능사관학교

인공지능 사관학교 - 2주차 (9일차, 웹크롤링)

곰종 2024. 6. 7. 21:44

1. 수업 목표

  • 웹 크롤링의 기초 이해
    • HTML 구조와 웹 페이지 요소를 이해하고, 이를 통해 데이터를 추출하는 방법을 배웁니다.
  • 파이썬 라이브러리 활용
    • Requests와 BeautifulSoup 같은 파이썬 라이브러리를 이용하여 웹 페이지에서 데이터를 효율적으로 수집하는 방법을 배웁니다.
  • 동적 웹 페이지 처리
    • Selenium을 사용하여 JavaScript로 동적으로 렌더링되는 웹 페이지에서 데이터를 추출하는 방법을 학습합니다.
  • 데이터 저장 및 분석
    • 수집한 데이터를 CSV나 JSON 파일로 저장하고, 기본적인 데이터 전처리 및 분석 방법을 배웁니다.
  • 크롤링 실제 활용
    • 실제 프로젝트를 통해 뉴스 기사 데이터를 수집하고, 이를 분석하여 의미 있는 정보를 도출하는 과정을 경험합니다.

웹 크롤링의 개념

  • 웹 크롤링(Web Crawling)
    • 자동화된 스크립트를 사용하여 인터넷 상의 웹 페이지를 방문하고 데이터를 수집하는 과정
    • 웹 크롤링을 통해 웹 사이트의 텍스트, 이미지, 링크 등 다양한 정보를 수집
  • 크롤러(Crawler)
    • 웹 크롤링을 수행하는 프로그램 또는 스크립트
    • 웹 페이지의 구조를 이해하고, 필요한 데이터를 추출하여 저장합니다.
  • 스크래핑(Scraping)
    • 특정 웹 페이지에서 필요한 데이터를 추출하는 과정
    • 웹 크롤링과 스크래핑은 종종 혼용되어 사용되지만, 스크래핑은 크롤링의 일부분으로 볼 수 있습니다.

 

웹 크롤링의 활용 사례

  • 데이터 수집 및 분석: 기업들은 웹 크롤링을 통해 경쟁사 분석, 시장 조사, 고객 리뷰 분석 등 다양한 목적으로 데이터를 수집하고 분석합니다.
    • 예: e-커머스 사이트에서 상품 리뷰를 수집하여 분석
  • 뉴스 및 정보 수집: 뉴스 기사, 블로그 포스트 등 최신 정보를 수집하여 트렌드 분석이나 여론 조사를 수행합니다.
    • 예: 특정 주제에 대한 뉴스 기사를 수집하여 트렌드 분석
  • 학술 연구: 연구자들은 웹 크롤링을 통해 대량의 데이터를 수집하여 연구에 활용합니다.
    • 예: 소셜 미디어 데이터를 수집하여 사회적 현상 분석
  • 부동산 정보 수집: 부동산 웹사이트에서 매물 정보를 수집하여 가격 비교 및 시장 분석에 활용합니다.
    • 예: 부동산 매물 정보를 수집하여 지역별 가격 변동 분석
  • 주식 및 금융 데이터 수집: 금융 웹사이트에서 주식 시세, 뉴스 등을 수집하여 투자 분석에 활용합니다.
    • 예: 주식 시세 데이터를 수집하여 투자 전략 수립

웹 크롤링의 장점 및 한계

  • 장점:
    • 대량의 데이터를 자동으로 수집할 수 있어 효율적
    • 다양한 출처에서 데이터를 통합하여 분석 가능
    • 사람의 개입 없이 24시간 데이터를 수집할 수 있음
  • 한계:
    • 웹사이트의 구조가 변경되면 크롤러가 작동하지 않을 수 있음
    • 웹 크롤링은 법적, 윤리적 이슈를 동반할 수 있음
    • 동적 웹 페이지의 경우, 크롤링이 어려울 수 있음

 

웹 크롤링 시 주의사항

1. 법적 이슈

  • 로봇 배제 표준(Robots.txt): 많은 웹사이트는 robots.txt 파일을 통해 크롤러가 접근할 수 있는 영역과 접근할 수 없는 영역을 지정합니다. 크롤러는 이 파일을 확인하고 규칙을 준수해야 합니다.
    • 예: User-agent: * Disallow: /private/💡 HTTP 통신의 헤더 부분입니다.
  • 저작권: 웹 크롤링을 통해 수집한 데이터가 저작권으로 보호될 수 있습니다. 특히, 상업적 목적으로 데이터를 사용할 경우 저작권 문제를 사전에 해결해야 합니다.
  • 서비스 약관: 웹사이트의 서비스 약관(Terms of Service)에는 크롤링에 대한 규정이 포함될 수 있습니다. 약관을 위반할 경우 법적 문제가 발생할 수 있습니다.
  • 개인정보 보호: 개인정보가 포함된 데이터를 수집할 경우 개인정보 보호법을 준수해야 합니다. 예를 들어, 사용자 데이터 수집 시 GDPR(유럽 일반 데이터 보호 규칙)이나 CCPA(캘리포니아 소비자 개인정보 보호법) 등을 준수해야 합니다.

2. 윤리적 고려사항

  • 과도한 요청 피하기: 웹 크롤링은 웹 서버에 부하를 줄 수 있습니다. 과도한 요청을 보내지 않도록 주의해야 하며, 적절한 딜레이를 설정하는 것이 좋습니다.
    • 예: 각 요청 사이에 1-2초 간격 두기
  • 공정 사용: 수집한 데이터를 사용할 때 공정 사용 원칙(Fair Use)을 준수해야 합니다. 이는 데이터 사용 목적, 성격, 양 등을 고려하여 공정하게 사용하는 것을 의미합니다.
  • 투명성: 데이터를 수집할 때 가능한 한 투명하게 작업하고, 필요 시 데이터 소유자에게 알리는 것이 좋습니다.

3. 기술적 주의사항

  • 웹사이트 구조 변경: 웹사이트의 구조가 변경되면 크롤러가 작동하지 않을 수 있습니다. 이를 해결하기 위해 크롤러를 지속적으로 업데이트해야 합니다.
  • IP 차단: 빈번한 요청으로 인해 IP가 차단될 수 있습니다. 이를 피하기 위해 프록시 서버를 이용하거나 요청 빈도를 조절해야 합니다.
  • CAPTCHA 회피: 일부 웹사이트는 봇을 막기 위해 CAPTCHA를 사용합니다. 이를 우회하기 위해서는 CAPTCHA 솔버를 사용하거나 사람이 직접 해결해야 합니다.
  • 반복 가능성: 크롤러는 여러 번 실행할 수 있어야 하며, 각 실행 결과가 일관되게 나와야 합니다. 이를 위해 코드를 잘 관리하고 테스트해야 합니다.

실습 - robots.txt 파일 분석

💡 관심 있는 사이트들의 robots.txt 파일을 분석해봅니다.

 

google.com의 접근이 가능한 영역

2. 정적 웹 페이지와 동적 웹 페이지

정적 웹 페이지 (Static Web Page)

  • 정의: 정적 웹 페이지는 서버에 저장된 HTML 파일을 클라이언트(웹 브라우저)에게 그대로 전달하는 웹 페이지입니다. 페이지의 내용은 변경되지 않으며, 모든 사용자가 동일한 콘텐츠를 보게 됩니다.
  • 특징:
    • 서버에서 HTML, CSS, JavaScript 파일을 클라이언트로 전달
    • 사용자와의 상호작용이 제한적
    • 서버 요청 시 동일한 콘텐츠 제공
    • 예: 개인 포트폴리오 웹사이트, 간단한 정보 제공 사이트

동적 웹 페이지 (Dynamic Web Page)

  • 정의: 동적 웹 페이지는 서버 또는 클라이언트 측에서 생성된 데이터를 기반으로 페이지가 동적으로 구성되는 웹 페이지입니다. 사용자의 행동이나 데이터베이스의 변경에 따라 실시간으로 내용이 업데이트됩니다.
  • 특징:
    • 서버 측 스크립트(PHP, ASP.NET 등) 또는 클라이언트 측 스크립트(JavaScript)로 생성
    • 사용자 입력에 따라 다른 콘텐츠 제공
    • 데이터베이스와 상호작용 가능
    • 예: 소셜 미디어, 전자상거래 사이트, 뉴스 포털

동적 웹 페이지 처리가 왜 필요한가?

1. 동적 콘텐츠 제공:

  • 동적 웹 페이지는 사용자 맞춤형 경험을 제공합니다. 예를 들어, 전자상거래 사이트는 사용자의 이전 구매 내역을 기반으로 제품을 추천합니다.

2. 실시간 데이터 업데이트:

  • 동적 웹 페이지는 실시간으로 데이터를 업데이트하여 최신 정보를 사용자에게 제공합니다. 뉴스 사이트나 주식 거래 사이트가 이에 해당합니다.

3. 사용자 상호작용:

  • 동적 웹 페이지는 사용자와의 상호작용을 통해 더 풍부한 사용자 경험을 제공합니다. 예를 들어, 댓글 시스템이나 실시간 채팅 기능이 있습니다.

동적 웹 페이지 크롤링의 어려움과 처리 방법

왜 크롤링이 어려운가?

  • JavaScript로 렌더링: 동적 웹 페이지는 서버에서 기본 HTML을 전송한 후, JavaScript가 실행되어 콘텐츠를 로드하거나 변경합니다. 단순한 HTML 파싱으로는 이러한 데이터를 얻을 수 없습니다.
  • AJAX 요청: 많은 동적 웹 페이지는 AJAX 요청을 통해 서버와 비동기적으로 데이터를 주고받습니다. 이러한 데이터는 초기 페이지 로드 시 존재하지 않으며, JavaScript가 실행된 후에야 나타납니다.

3. HTML 및 웹 페이지 구조 이해

1. HTML 기본 구조

  • HTML(Document Object Model): HTML은 웹 페이지의 구조를 정의하는 마크업 언어입니다. HTML 문서는 요소로 구성되며, 각 요소는 태그로 감싸여 있습니다.
    • 예: <html>, <head>, <body>, <div>, <p>, <a> 
  • 기본 구조: HTML 문서는 기본적으로 아래와 같은 구조를 가집니다.

2. 주요 HTML 요소

  • 헤더 요소(head): 문서의 메타데이터를 포함합니다. 예: <title>, <meta>, <link>, <style>, <script>
  • 본문 요소(body): 웹 페이지의 주요 콘텐츠를 포함합니다. 예: <header>, <nav>, <section>, <article>, <footer>
  • 텍스트 요소: 텍스트 콘텐츠를 정의합니다. 예: <h1>, <p>, <span>, <strong>, <em>
  • 링크 요소: 다른 페이지로 연결하는 하이퍼링크를 정의합니다. 예: <a href="URL">Link Text</a>
  • 이미지 요소: 이미지를 포함합니다. 예: <img src="image.jpg" alt="Description">
  • 리스트 요소: 목록을 정의합니다. 예: <ul>, <ol>, <li>

3. 웹 페이지 구조 이해

  • DOM 트리: HTML 문서는 트리 구조로 표현됩니다. 각 HTML 요소는 노드로서 DOM(Document Object Model)을 구성합니다.
    • 예: <html>은 루트 노드, <body>, <head>는 자식 노드
  • 속성(Attribute): HTML 요소는 속성을 가질 수 있습니다. 예: <a href="URL" target="_blank">Link Text</a>
  • 클래스와 ID: 스타일링과 스크립팅을 위해 HTML 요소에 클래스와 ID를 지정할 수 있습니다.
    • 예: <div class="container">, <h1 id="main-title">

4. CSS 선택자 이해

  • CSS 선택자: 웹 페이지에서 원하는 요소를 선택하고 스타일을 적용하는 방법을 이해하는 것이 중요합니다. 크롤링 시에도 요소를 선택할 때 사용됩니다.
    • 기본 선택자: element, .class, #id
    • 복합 선택자: element.class, element#id, element > child, element + sibling, element ~ sibling
    • 예: .container > .item, #main-title + p

 

4. 파이썬 크롤링 도구 소개

웹 크롤링을 위해 파이썬에서 주로 사용되는 두 가지 주요 라이브러리는 Requests와 BeautifulSoup입니다. 이 두 라이브러리는 함께 사용되어 웹 페이지에서 데이터를 쉽게 수집할 수 있도록 도와줍니다.

1. Requests 라이브러리

  • 소개: Requests는 HTTP 요청을 보내고 응답을 받을 수 있게 해주는 파이썬 라이브러리입니다. 이를 통해 웹 페이지의 HTML 소스를 가져올 수 있습니다.
  • 설치: pip install requests
  • 기본 사용법:

2. BeautifulSoup 라이브러리

  • 소개: BeautifulSoup은 HTML 및 XML 파일을 파싱하고 탐색할 수 있게 해주는 파이썬 라이브러리입니다. 이를 통해 원하는 데이터 요소를 쉽게 추출할 수 있습니다.
  • 설치: pip install beautifulsoup4
  • 기본 사용법:

 

실습

문제

다음과 같은 HTML 파일을 사용한다고 가정합니다:

 

문제: BeautifulSoup을 사용하여 다음을 수행하세요.

  1. ID가 main-title인 요소의 텍스트를 가져와 출력하세요.
  2. 클래스 이름이 description인 요소의 텍스트를 가져와 출력하세요.
  3. 태그 이름이 li인 모든 요소를 찾아 각각의 텍스트를 출력하세요.
  4. 링크 텍스트가 example@example.com인 요소의 href 속성을 가져와 출력하세요.
  5. CSS 선택자를 사용하여 ID가 main-title인 요소의 텍스트를 가져와 출력하세요.
  6. CSS 선택자를 사용하여 클래스 이름이 description인 요소의 텍스트를 가져와 출력하세요.
  7. CSS 선택자를 사용하여 ul 태그 안에 있는 클래스 이름이 item인 모든 li 요소를 찾아 각각의 텍스트를 출력하세요.

 

5. BeautifulSoup을 이용한 데이터 추출 심화

BeautifulSoup은 HTML 및 XML 파일을 파싱하고 탐색할 수 있게 해주는 파이썬 라이브러리로, 다양한 방법으로 데이터를 추출할 수 있습니다. 이번 섹션에서는 find, find_all 메서드 사용법과 CSS 선택자를 이용한 요소 선택 방법을 심화 학습합니다.

1. find 메서드 사용법

  • 기능: find 메서드는 조건에 맞는 첫 번째 HTML 요소를 반환합니다.
  • 구문: soup.find(name, attrs, recursive, string, **kwargs)
    • name: 태그 이름 (예: 'div', 'p', 'a' 등)
    • attrs: 속성으로 요소를 필터링 (예: {'class': 'my-class'})
    • recursive: 자식 요소들을 탐색할지 여부 (기본값: True)
    • string: 텍스트로 요소를 필터링
    • *kwargs: 추가적인 속성 필터링 (예: id='main')

 

2. find_all 메서드 사용법

  • 기능: find_all 메서드는 조건에 맞는 모든 HTML 요소를 리스트로 반환합니다.
  • 구문: soup.find_all(name, attrs, recursive, string, limit, **kwargs)
    • name, attrs, recursive, string: find 메서드와 동일
    • limit: 반환할 요소의 최대 개수

예제:

3. CSS 선택자를 이용한 요소 선택

  • 기능: select 메서드는 CSS 선택자를 사용하여 조건에 맞는 모든 HTML 요소를 리스트로 반환합니다.
  • 구문: soup.select(selector, limit)
    • selector: CSS 선택자 (예: '.my-class', '#main', 'div > p')
    • limit: 반환할 요소의 최대 개수

예제:

 

6. 웹 페이지에서 테이블 데이터 추출

웹 페이지에서 테이블 데이터를 추출하는 것은 매우 일반적인 작업입니다. BeautifulSoup을 사용하여 HTML 테이블 데이터를 파싱하고 원하는 형식으로 추출하는 방법을 학습해보겠습니다.

1. 테이블 데이터 추출 과정

  • 단계 1: 웹 페이지의 HTML 소스를 Requests를 사용하여 가져옵니다.
  • 단계 2: BeautifulSoup을 사용하여 HTML 소스를 파싱합니다.
  • 단계 3: find 또는 find_all 메서드를 사용하여 테이블 요소를 찾습니다.
  • 단계 4: 테이블 행(<tr>)과 셀(<td>, <th>)을 반복하면서 데이터를 추출합니다.

7. 동적 웹 페이지 이해와 Selenium 사용법

동적 웹 페이지는 클라이언트 측(JavaScript)에서 콘텐츠를 생성하거나 업데이트하는 웹 페이지를 의미합니다. 이런 페이지는 서버에서 HTML을 완전히 제공하지 않고, 웹 브라우저가 JavaScript 코드를 실행하여 콘텐츠를 로드하거나 업데이트합니다. 이러한 특성 때문에 정적 HTML 페이지와는 다르게 크롤링하는 방법이 필요합니다.

1. 동적 웹 페이지의 특징

  • JavaScript 실행: 페이지 로드 시 JavaScript가 실행되어 콘텐츠가 동적으로 변경됩니다.
  • Ajax 요청: JavaScript는 서버에 추가 요청을 보내어 데이터를 가져와 페이지를 업데이트합니다.
  • SPA(Single Page Application): URL 변경 없이 페이지 내에서 동적으로 콘텐츠를 로드하여 사용자 경험을 향상시킵니다.

2. 동적 웹 페이지 크롤링 방법

동적 웹 페이지에서 데이터를 추출하려면 JavaScript를 실행할 수 있는 도구를 사용해야 합니다. 가장 일반적으로 사용되는 도구는 Selenium입니다.

3. Selenium 사용법 소개

Selenium은 웹 브라우저를 자동화하는 도구로, 웹 브라우저를 실제 사용자처럼 조작할 수 있습니다. 이를 통해 JavaScript가 렌더링한 콘텐츠를 크롤링할 수 있습니다.

설치:

  • Selenium 라이브러리: pip install selenium
  • 웹 드라이버: 크롤링하려는 브라우저에 맞는 웹 드라이버를 설치합니다. (예: ChromeDriver, GeckoDriver)

기본 사용법:

 

8. 크롤링한 데이터 저장 및 처리

웹 크롤링을 통해 수집한 데이터를 유용하게 사용하기 위해서는 적절한 형식으로 저장하고, 필요에 따라 데이터를 전처리 및 분석하는 과정이 필요합니다. 이번 섹션에서는 CSV 및 JSON 파일로 데이터를 저장하는 방법과 간단한 데이터 전처리 및 분석 방법을 학습합니다.

1. CSV 파일로 데이터 저장

CSV(Comma-Separated Values) 파일은 데이터를 테이블 형태로 저장하는 간단한 텍스트 파일 형식입니다. 파이썬에서는 pandas 라이브러리를 사용하여 데이터를 CSV 파일로 쉽게 저장할 수 있습니다.

설치:

  • pandas 라이브러리 설치: pip install pandas

예제 코드:

 

2. JSON 파일로 데이터 저장

JSON(JavaScript Object Notation) 파일은 데이터를 구조화된 형식으로 저장하는 파일 형식입니다. 파이썬에서는 json 모듈을 사용하여 데이터를 JSON 파일로 저장할 수 있습니다.

예제 코드:

 

 

9. 심화 크롤링 및 프로젝트

이번 섹션에서는 네이버 예약 사이트에서 예약 현황을 수집하는 실습을 진행해봅니다.

실습 코드

 

 

설명:

  • selenium: 웹 페이지의 자동화를 위한 도구입니다. 웹 브라우저를 열고 조작할 수 있습니다.
  • webdriver: Selenium의 웹 드라이버 모듈로, 웹 브라우저를 제어합니다.
  • By: Selenium의 모듈로, HTML 요소를 찾기 위한 다양한 방법을 제공합니다.
  • BeautifulSoup: HTML 및 XML 파일을 파싱하는 라이브러리입니다.

이 코드에서는 Chrome 드라이버를 설정하고 있습니다. Chrome 드라이버는 Chrome 브라우저를 자동화하기 위해 사용됩니다. 다른 브라우저를 사용할 수도 있으며, 예를 들어 Firefox를 사용하려면 webdriver.Firefox()를 사용합니다.

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

설명:

  • driver.get(url): 지정된 URL을 엽니다.
  • driver.implicitly_wait(10): 요소를 찾을 때까지 최대 10초까지 대기합니다. 요소가 즉시 나타나지 않더라도 대기하며, 나타나면 즉시 다음 작업을 수행합니다. 이 방법은 웹 페이지의 로딩 시간을 처리하는 데 유용합니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

설명:

  • driver.find_elements(By.CSS_SELECTOR, 'a.calendar-date'): CSS 선택자를 사용하여 a.calendar-date 클래스가 있는 모든 요소를 찾습니다. find_elements는 여러 요소를 찾고 리스트를 반환합니다. 반대로 find_element는 첫 번째 요소만 반환합니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

설명:

  • 예약 시간대 정보를 저장할 빈 리스트를 초기화합니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

설명:

  • for date_button in calendar_dates: 각 날짜 버튼에 대해 반복합니다.
  • date_button.click(): 현재 날짜 버튼을 클릭합니다.
  • time.sleep(2): 페이지가 로드될 시간을 주기 위해 2초간 대기합니다. time.sleep을 사용하는 대신 driver.implicitly_wait를 사용할 수도 있습니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

설명:

  • html = driver.page_source: 현재 페이지의 HTML 소스를 가져옵니다.
  • soup = BeautifulSoup(html, 'lxml'): BeautifulSoup을 사용하여 HTML 소스를 파싱합니다. 여기서는 lxml 파서를 사용합니다. 다른 파서로는 html.parser 등이 있습니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

설명:

  • date_info = date_button.find_element(By.CSS_SELECTOR, 'span.num').text: 날짜 버튼 내부의 날짜 정보를 추출합니다.
  • timeslots = soup.select('div.time_box_wrap li.item'): CSS 선택자를 사용하여 시간대 정보를 포함하는 모든 li.item 요소를 찾습니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

설명:

  • 각 시간대에 대해 반복하며 시간과 예약 가능 여부를 추출합니다.
  • slot.select_one('span.box_info').text.strip(): 시간 정보를 추출하고 공백을 제거합니다.
  • slot.select_one('span.box_info2').text.strip(): 예약 가능 여부를 추출하고 공백을 제거합니다.
  • 추출한 정보를 date_time_info 리스트에 저장합니다.
  • 예외가 발생할 경우 해당 날짜 버튼과 오류 메시지를 출력합니다.
  • 종료 시, 브라우저를 닫고 Selonium 세션을 종료합니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

설명:

  • 수집된 날짜 및 시간대 정보를 출력합니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

설명:

  • csv 모듈을 사용하여 결과를 CSV 파일로 저장합니다.
  • with open('date_time_info.csv', 'w', newline='', encoding='utf-8') as csvfile: CSV 파일을 쓰기 모드로 엽니다.
  • fieldnames: CSV 파일의 헤더를 정의합니다.
  • csv.DictWriter: 딕셔너리를 CSV 파일로 작성할 수 있는 객체를 생성합니다.
  • writer.writeheader(): 헤더를 작성합니다.
  • 각 정보를 CSV 파일에 작성합니다.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

실습2 

네이버의 "광주날씨" 를 검색 후, 10일간의 날씨를 크롤링하기