selenium과 beautifulSoup을 사용한 웹 페이지 수집 1

IT/크롤링 2025. 1. 4. 22:41

개요

selenium을 사용하여 웹 페이지 오픈과 상호작용을 담당하고, beautifulSoup을 사용하여 페이지에서 정보를 수집한다.

from selenium import webdriver
from bs4 import BeautifulSoup


url = ''

options = webdriver.ChromeOptions()

options.add_argument("--start-maximized")
# options.add_argument("--headless") # 웹 브라우저를 화면에 띄우지 않음

driver = webdriver.Chrome(options=options)

driver.get(url)

page_source = driver.page_source

soup = BeautifulSoup(page_source, 'html.parser')

가장 기본적인 코드는 위와 같고, soup를 통해 웹 페이지 파싱을 할 수 있다.
request와 같은 라이브러리르 사용하여 개발자 도구의 network탭에서 알아낸 API를 역추척하여 API 호출을 모방할 수 있다.
API를 호출하는 방법으로도 데이터를 가져올 수 있지만 여기서는 selenium을 이용하여 데이터를 로드한 후, beautifulSoup를 사용하여, 페이지에서 데이터를 추출해본다.

테스트를 위해 웹 페이지의 코드를 확인할 때는 아래 코드를 사용하면, beautifulSoup로 파싱한 웹 페이지를 간단히 확인해볼 수 있지만 대다수의 코드는 매우 길어서 전체 코드를 확인하기 보다, 일부분에 해당하는 코드를 확인하면 좋을 것 같다.
BeautifulSoup의 prettify() 메소드는 웹 소스코드를 포맷에 맞게 만들어 준다.
직접 콘솔로 확인하기에는 무리가 있겠지만, 확인을 해야 한다면 나쁘지 않을 수 있다.

soup = BeautifulSoup(page_source, 'html.parser')
print(soup.prettify())

selenium를 사용한 상호작용: 호버

또한 웹 페이지에서 서브 메뉴 처럼 마우스를 호버시에만 나타나는 코드의 경우에는 Action을 사용하여 스크립트를 작성할 수 있다.

rom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains 
from bs4 import BeautifulSoup
import time

url = ''

options = webdriver.ChromeOptions()

options.add_argument("--start-maximized")
options.add_argument("--headless")

driver = webdriver.Chrome(options=options)

driver.get(url)

about_el = driver.find_element(By.CSS_SELECTOR, "[href='/about']")
work_el = driver.find_element(By.CSS_SELECTOR, "[href='/works/design']")

# move to about page
about_el.click()
time.sleep(3)
driver.get_screenshot_as_file("about_page.png")

# go back to home
driver.back()

# works menu hover
ActionChains(driver).move_to_element(work_el).perform()
time.sleep(3)

# get sub menu list
sub_menu_works_el = driver.find_element(By.CSS_SELECTOR, "[href='/works/design']+ul")
sub_menu_works_html = sub_menu_works_el.get_attribute("innerHTML")
sub_menu_works_soup = BeautifulSoup(sub_menu_works_html, "html.parser")

print(sub_menu_works_el.text)
print(sub_menu_works_soup.prettify())

driver.quit()

스크린 샷 저장

driver.get_screenshot_as_file('insta_login.png')

드라이버 객체의 get_screenshot_as_file을 사용하여 파일이름 및 경로를 지정하면 현재 화면을 그대로 캡처한다.
파일 이름은 반드시 png 파일 확장자로 끝나야 한다.

instagram 로그인 스크립트 구성

로그인 과정을 진행하기 위해서는 여러 과정이 필요하다
인스타에서는 메인 페이지 접속 시, 메인 페이지에서 로그인을 하거나, /accounts/loing 페이지에서 로그인 폼을 입력하게 된다.
/accounts/login 페이지에서 로그인 폼을 입력하기 전에는 splash screen이 표시되므로, 해당 splash screen이 종료되기까지 기다리는 과정이 필요하다.

selenium에서는 특정 엘리멘트가 화면에 표시된 상태인지를 알 수 있는 메소드를 지원하므로 해당 메소드를 사용한다.
개발자 도구를 통해 알아낸, splash screen의 id은 splash-screen으로, 엘리멘터의 is_displayed()메소드를 사용해, splash screen이 사라지기를 기다린다.

# splash screen end wait
while True:
  is_dispaly = driver.find_element(By.ID, "splash-screen").is_displayed()
  print("waiting...", is_dispaly)
  time.sleep(3)
  if is_dispaly:
    print("end splash screen")
    break