본문 바로가기
Backend/Python

[python] Selenium & Bs4 웹 스크래핑

by 천우산__ 2023. 3. 22.

토이 프로젝트에 사용될 DB 적재를 위해 네이버에서 연재중인 웹툰의 이미지, 제목, 설명이 필요해서 

처음에는 Bs4 패키지를 이용해서 웹툰 리스트 정보 스크래핑을 시도했다.

 

import requests 
from bs4 import BeautifulSoup

url = "https://comic.naver.com/webtoon"
html = requests.get(url, 'html.parser')
print(html)

결과를 확인해보니, 화면 상으로 보고 있는 html 코드 보다 더 작은 양의 데이터만 가져와 진 것이 확인되었다.

 

Python을 이용해 불러온 데이터

 

위에서 작성한 코드로 불러온 데이터에서 원하는 정보가 하나도 없었기 때문에

스크래핑에 사용할 패키지를 변경하였다. (Bs4 > Selenium)

 

두 패키지의 가장 큰 차이점은, 동적 임무를 수행할 수 있느냐, 없느냐로 나눠진다.

 

특정 버튼을 클릭을 통해서만 html 요소가 공개되는 데이터가 존재하는 페이지를 가정했을때

bs4에서는 해당 버튼을 식별할 수 없지만, selenium 은 '특정 버튼 클릭' 동작을 수행하는 코드 추가를 통해 해당 버튼을 식별할 수 있다.

 

그리고, 이번에 다시 알게 된 것은

bs4 파싱을 위해 requests.get으로 받아온 페이지 url 데이터는 페이지 우클릭 시에 확인할 수 있는 '페이지소스' 였으며,

selenium의 경우, driver로 보고 있는 화면 내의 html 정보를 가져온다는 점이었다.

 

아래 이미지는 bs4와 selenium으로 각각 https://comic.naver.com/webtoon 페이지를 크롤링 한 결과이다.

selenium 패키지로 html 데이터를 받아오는 경우

 

requests.get 요청 후 bs4로 파싱한 경우 - 페이지 소스 보기와 같은 데이터

 

내가 보고 있는 화면에서는 웹툰 정보가 있으므로, selenium 패키지를 통해

요일별 웹툰 전체의 세부 링크를 추출하여 리스트 형태로 저장하였다.

 

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import requests

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
url_base = "https://comic.naver.com"
driver.get(url_base + "/webtoon")
driver.implicitly_wait(3) # 페이지 로딩 후 3초간 대기, 로딩 이전 다음 동작(12번째 줄 이하) 시도 시 오류 발생

page_source = driver.page_source
html = BeautifulSoup(page_source, 'html.parser') # 현재 화면 소스 Bs4로 전달

webtoon_link_list = html.select('li.DailyListItem__item--LP6_T > div >  a.ContentTitle__title_area--x24vt') # 웹툰별 소개 링크 영역
detail_link = [] # 이후 동작을 위한 세부 링크 데이터 저장 리스트

for w in webtoon_link_list:
    detail_link.append(w['href']) # 순차적 저장

 

그 후, 웹툰 세부 링크 리스트를 순회하며 1. 웹툰 대표 이미지 2. 제목 3. 소개글을 수집하였는데

이번에도 request.get으로 요청한 데이터와 실제 화면에서 보이는 html 구조는 달랐지만

 

원하는 데이터는 모두 있었기 때문에 selenium이 아닌, request.get 으로 페이지 데이터를 받아와 필요한 데이터를 추출하였다.

 

for dlink in detail_link: # 저장한 세부 링크 리스트를 순회하며
    goal_link = url_base + dlink 
	
    # 페이지 데이터를 요청하고, bs4에 전달
    webtoon_detail = requests.get(goal_link)
    detail_html = BeautifulSoup(webtoon_detail.text, 'html.parser')
	
    # 각각 제목, 설명글, 이미지 소스 url
    title = detail_html.select_one('meta[property="og:title"]')['content']
    description = detail_html.select_one('meta[property="og:description"]')['content']
    img = detail_html.select_one('meta[property="og:image"]')['content']

    print(title, description, img)