[크롤링]API 와 크롤링 - 2회차

Arin lee·2025년 1월 3일
0

contents

  • 크롤링과 스크래핑
  • BeautifulSoup, Selenium
  • python 실습 - CGV Review Crawling

summary

  1. 크롤링과 스크래핑
    ☑️ 개념

    🎯웹 크롤링: 웹상에 존재하는 모든 웹 페이지를 방문하여 데이터를 수집하는 방법.
    크롤러는 인터넷 상의 모든 페이지를 방문하며, 각 페이지의 링크를 따라가면서 자동으로 데이터를 수집하기에 규칙에 따라 자동으로 웹 문서를 탐색하는 컴퓨터 프로그램, 크롤러의 개념이탄생하게 되었다.

🎯웹 스크래핑: 특정 웹 사이트나 페이지에서 필요한 데이터를 자동으로 추출해 내는 것을 의미. 원하는 정보를 추출하기 위해 HTTP GET 요청을 보냄. 정상응답을 받는 경우, 스크
래퍼는 HTML 코드를 분석하여 데이터를 추출.

🎯공통점: 원하는 데이터를 수집할 수 있다는 점에서 공통점을 지니고 있다. 기술적으로
(python)으로 함께 사용되는 경우가 많다. (웹 크롤링을 통한 웹접근 → 스크래핑을 통한특정 데이터 추출)

🎯차이점: 웹 크롤링은 웹사이트에 대한 정보를 색인화하고 저장하는 데 사용되는 반면, 웹 스크래핑은 분석 및 기타 목적을 위해 웹사이트에서 데이터를 추출하는 데 사용.

또한 웹 크롤링은 일반적으로 검색 엔진 및 기타 자동화 도구에 의해 수행되는 반면 웹 스크래핑은 종종 사람 또는 이 목적을 위해 특별히 설계된 자동화 도구에 의해 수행.

  • ☑️ 주의사항
    🎯 합법인지 확인 : (=로봇 배제 표준(Robots Exclusion Standard)을 준수했는가)
    로봇 배제 표준은 웹 사이트의 소유자가 로봇에 대한 액세스 권한을 제어하는 프로토콜(통신방식). 따라서, 스크래핑/크롤링을 수행하기 전에 해당 웹 사이트의 robots.txt 파일을 반드시 확인하고, 로봇 배제 표준을 준수하는지 확인하는 과정이 필요.
    → robots.txt 파일은 URL 뒤 robots.txt 를 붙여 확인할 수 있다.
https://www.youtube.com/robots.txt

⚠️youtube 댓글 수집은 허용되지 않는다.

  • ☑️ 웹(WEB) 의 구성요소
    웹 사이트 구현을 위해 HTML, CSS, javascript 세가지가 사용되는데, 역할은 아래와 같다.
    우리는 이 중 HTML 을 통해 원하는 데이터의 경로를 찾아보겠다.
    • HTML (Hyper Text Markup Language) : 웹 사이트의 뼈대를 만들어 줌.
    • CSS (Cascading Style Sheets) : 예쁘게 꾸며서 표현해 줌.
    • javascript : 동작하게 만들어 줌.
  • ☑️ HTML 의 구조 & XPATH
    🎯 크롤링 및 스크래핑을 위해 HTML 의 개념 및 구조 파악은 필수!
    HTML은 HyperText Mark-up Language 의 약어로 프로그래밍 언어가 아니라 문서를 설명해주는 정보를 표현하는 마크업 언어(=태그로 둘러쌓인 언어=<>). 문서의 내용 이외의 문서의 구조나 서식 같은 것을 포함하고 있다. ⚠️ HTML은 웹 페이지를 구성하는 골격으로 아래와 같은 구성요소로 이뤄져 있다.
    아래 구조는 웹 페이지 개발에 기본 뼈대이며, 웹 브라우저가 올바르게 해석하여 사용자에게 보여줄 데이터와 개발 컨텐츠를 구분하여 표시.
  • 문서 형식 선언(Doctype): 문서 형식 선언(Doctype)은 HTML 문서가 어떤 버전의 HTML이나 XHTML로 작성되었는지 웹 브라우저에게 알려주는 역할.
  • 루트 요소(html): 루트 요소는 HTML 문서의 최상위 요소이며, 다른 HTML 요소들을 포함하는 부모 요소.
  • 헤드(Head):  HTML 문서의 메타데이터와 외부 리소스에 대한 정보를 포함하는 부분. 화면에 직접적으로 보이지 않지만, 웹 브라우저가 문서를 처리하고 표시하는 데 중요한 역할.
  • 본문(Body): HTML 문서의 실제 내용을 담고 있는 부분. 웹 페이지를 구성하는 모든 텍스트, 이미지, 링크, 테이블, 폼 등의 콘텐츠가 포함.
  • 예시. CGV 메인 페이지 > 예매 화면.
  • 키보드의 F12 버튼을 누르면, HTML 구조를 확인하실 수 있다.
    • body 부분의 nav_menu 하위 항목인 것을 확인 할 수 있다.
  • 우리는 실습 과정에서 이를 XPATH 라는 경로로 정의하고, 실습에 적용.
  • ⚠️ XPath는 'XML Path Language'의 줄임말로, XML 문서의 특정 요소 또는 속성에 접근하기 위한 경로를 지정하는 언어.
  • XPATH 를 찾는 방법은 아래와 같다. 경로에 마우스 오른쪽 커서를 두어 XPATH 를 복사할 수 있다.
  • 주요 개념
    • div 태그: 분할하다는 뜻의 Division의 준말로, HTML문서 내에서 한 개의 가로 공간(Block)을 만드는 태그.
    • p 태그: 단락, 절이라는 뜻의 Paragraph의 준말로, 주로 문장에 대해서 사용하는 태그이며 역시 한 개의 가로 공간(Block)을 만드는 태그입.
    • 모든 태그에는 id 속성과 class 속성을 지정해 줄 수 있는데, 이를 이용하면 CSS나 JavaScript에서 태그를 좀더 쉽게 다룰 수 있다.
      • class: java 에서 객체를 만들어내기 위한 틀.
        → div class : ‘하나의 공간(클래스)를 만들겠다’.
  1. BeautifulSoup, Selenium
    :본격적으로 데이터를 추출하기 위한 라이브러리
  • ☑️ BeautifulSoup
    🎯 BeautifulSoup은 python 에서 웹데이터 크롤링을 위한 기초 라이브러리. HTML 태그를 기반으로 크롤링을 진행. 지난 시간에 배운 request 라이브러리를 기억하시나요? (requests는 HTTP 호출시 가장 많이 사용되는 라이브러리)
    즉 request 라이브러리를 통해 웹페이지를 호출하고, BeautifulSoup 라이브러리를 통해 웹에 접근된 상태에서 데이터를 추출(파싱). 두 라이브러리는 세트라고 할 수 있다. 해당 과정에서는 파싱의 개념이 활용. 웹 파싱이란 - 웹 상의 자연어, 컴퓨터 언어 등의 일련의 문자열들을 분석하는 프로세스로 정의.

🎯기본 사용방식은 아래와 같다.

#처음 1회 설치
#pip install beautifulsoup4
#pip install requests

import requests
from bs4 import BeautifulSoup as bs

url = "크롤링하려는 웹페이지의 주소"

# url에 담겨있는 http페이지 주소를 요청하여 그 주소의 요소들을 가져올 수 있도록 연결
response = requests.get(url)

# response라는 변수에 연결의 결과를 담고 
# response.content 으로 받아온 결과의 내용을 html.parser라는 html해석기로 내용을 html tag 구조로 해석합니다. 
soup = bs(response.content,"html.parser")

🎯간단한 예제

  • 가비아 라이브러리 사이트의 게시글 제목을 확인.
  • https://library.gabia.com/ 로 접속.
  • F12 버튼을 통해, HTML 구조를 확인.
  • python JupyterNotebook 을 통해, python3 file 을 생성하고 코드를 작성.
# 처음 1회 설치
#pip install beautifulsoup4
#pip install requests

import requests
from bs4 import BeautifulSoup as bs

# request 라이브러리를 통한 http 통신호출
page = requests.get("https://library.gabia.com/")

# beautifulsoup 라이브러리를 이용한 page의 text 데이터 파싱(문자열분석)
soup = bs(page.text, "html.parser")

# select 문법을 이용하여 html 내 필요한 부분을 모두 선택합니다. 
# div.esg-entry-content 에서 a 를 타고 그 아래로 span 을 타고 내려가서 text 를 불러옵니다.
elements = soup.select('div.esg-entry-content a > span')

# for 구문을 통해 반복적으로 수행해줍니다. 
for index, element in enumerate(elements, 1):
    print("{} 번째 게시글의 제목: {}".format(index, element.text))
  • 결과가 아래와 같이 도출되는 것을 확인가능
  • ☑️ Selenium
    🎯 Selenium은 완전히 크롤링을 위한 라이브러리가 아닌, 웹개발자들이 동적 웹이 제대로 작동하는지를 테스트하기 위해서 만들어진 모듈. 이 점이 웹 크롤링에서는 ‘동적 크롤링’이 가능하게 해 준다는 장점.
    앞서 설명한 BeutifulSoup 라이브러리의 경우, 웹페이지의 자바스크립트로 생성된 파트는 크롤링이 불가능. 쉽게말해 스크롤 및 화면이동, 버튼클릭 등의 바뀌는 부분은 Beutiful Soup으로 크롤링이 불가능. 이 부분은 Selenium 라이브러리가 대체할 수 있다.
    → 즉 셀레니움 라이브러리는 크롬 등의 브라우저를 자동으로 열어서 컨트롤하는 프레임워크 가되겠다. (⚠️ 금일 진행되는 메인 실습은 CGV 크롤링이며, 동적 크롤링을 기반으로 진행되기 때문에 Selenium Library 를 중심으로 진행.)
    🎯 Selenium 라이브러리 기능 중 하나인 WebDriver는 웹 어플리케이션을 테스팅할 때 사용하실 수 있는 기능을 탑재. 웹드라이버 구동 과정은 아래와 같다.
  • 해당 라이브러리를 위해서는, 아래 링크를 따라 크롬 브라우저를 다운그레이드 하여 python 크롤링 환경에 맞춰주는 과정이 필수.
  • https://hotel-iu.tistory.com/886 에 접속.
  • 114.0.5735.199 버전을 다운로드 해 줍니다.
  • 실습을 위한 사전 작업이 모두 끝!
  1. python 실습 - CGV Review Crawling
  • ☑️ 실습코드
    • find_elements_by_tag_name: Copy Element의 tag
    • find_elements_by_xpath: Copy XPath 또는 Copy full XPath
    • find_elements_by_id: Copy Element의 id attribute
    • find_elements_by_class_name: Copy Element의 class attribute
    • find_elements_by_link_text: Copy Element의 text
    • find_elements_by_partial_link_text: Copy Element의 text중 일부
    • find_elements_by_css_selector: Copy selector
    • sleep은 주어진 시간(초) 동안 코드 실행을 지연하는 데 사용되는 함수.
      • time.sleep(5) → 5초 정지
      • 크롤링 시, 반복문을 사용하게 되는데 → 이 때 짧은 시간동안 여러번 데이터에 접근할 셩우, 접속제한이 있을 수 있다. 이를 방지하기 위해 sleep 구문을 작성.
      • 이는 필수!
# pip install selenium
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time
import pandas as pd


import warnings # 경고창 무시
warnings.filterwarnings('ignore')

# 드라이버 설정 및 페이지넘버 설정(저는 12로 설정했어요)
# 함수 구현
def get_movie_reviews(url, page_num=12):
    chrome_driver =  'C:/Users/user-pc/Downloads/chromedriver_win32/chromedriver.exe'
    wd = webdriver.Chrome(chrome_driver)

    wd.get(url)
    # 빈 리스트 생성하기
    writer_list=[]
    review_list=[]
    date_list=[]
    like_list=[]
    for page_no in range(1,page_num+1): # 1페이지에서 page_num까지의 리뷰 추출
        try:
            page_ul = wd.find_element_by_id('paging_point') # 페이지 포인트 코드 추출
            page_a = page_ul.find_element_by_link_text(str(page_no))
            page_a.click()
            time.sleep(2) # 페이지 로딩까지의 시간 두기

            writers = wd.find_elements_by_class_name('writer-name')
            writer_list += [writer.text for writer in writers]
            
            reviews = wd.find_elements_by_class_name('box-comment')
            review_list += [ review.text for review in reviews ]
            
            dates = wd.find_elements_by_class_name('day')
            date_list += [date.text for date in dates]
            
            likes = wd.find_elements_by_id('idLikeValue')
            like_list += [like.text for like in likes]            
                    
            if page_no%10==0: # 10이상의 값을 만났을 때 다음 페이지로 넘기기 버튼
                    if page_no==10:
                        next_button = page_ul.find_element_by_class_name("paging-side")
                        #next_button = page_ul.find_element_by_class_name('btn-paging next')
                        next_button.click()
                        time.sleep(2)
                    else:
                        next_button = page_ul.find_element_by_xpath('//*[@id="paging_point"]/li[13]/button').click()
                        time.sleep(2)
        except NoSuchElementException:
                break
    movie_review_df = pd.DataFrame({"Writer" : writer_list,
                                   "Review" : review_list,
                                   "Date" : date_list,
                                   "Like" : like_list})
    wd.close()
    return movie_review_df


# url 과 pagenum 을 입력하여 작성자, 리뷰내용, 작성날짜, 좋아요 수 요청 및 dataframe 반환
#범죄도시4 movie_review_df = get_movie_reviews("http://www.cgv.co.kr/movies/detail-view/?midx=88104#", page_num=3905)
movie_review_df = get_movie_reviews("http://www.cgv.co.kr/movies/detail-view/?midx=85813", page_num=12)

# dataframe 저장 
movie_review_df.to_csv('범죄도시2크롤링.csv', index=False, encoding="utf-8-sig")

결과 (dataframe)

  • ☑️ 참고 자료 CSS 구조 확인하기 💁

key points

많은 기업들이 최근에는 크롤링을 막아두고 있다. 그럼에도 불구하고 허가하는 이유는?

  • 데이터 공유와 연구: 일부 웹사이트는 연구나 데이터 분석을 위해 데이터를 공유하고 싶어하며, 이를 통해 더 많은 가치를 창출할 수 있다.
  • API 제공: 많은 기업들이 공식 API를 통해 데이터를 제공하여, 개발자들이 합법적으로 데이터를 사용할 수 있도록 하고 있다. 이는 크롤링 대신 API를 통해 데이터를 수집하도록 유도.
  • 마케팅 및 홍보: 특정 웹사이트는 자신의 콘텐츠가 더 널리 퍼지기를 원할 수 있으며, 이를 통해 브랜드 인지도를 높일 수 있다.
  • 상호 이익: 크롤링을 허용함으로써 웹사이트는 더 많은 트래픽을 유도하거나, 다른 서비스와의 협력을 통해 상호 이익을 얻을 수 있다.
profile
Be DBA

0개의 댓글