1. 셀레니움 기초
이전에 배운 requests의 경우 웹 사이트에 요청을 보내고, BeautifulSoup로 원하는 정보를 가지고 왔다. 하지만 해당 방법은 동적 사이트 크롤링 등에 한계가 있다. 이를 위해 셀레니움을 사용할 수 있다. 셀레니움은 웹 어플리케이션 테스트를 위한 도구로 탄생했고, 브라우저를 띄워서 사람처럼 동작하게 만들 수 있다. 이 덕분에 스크롤될 때 데이터가 추가되는 동적 사이트 등을 크롤링 할 수 있다.
먼저 셀레니움 설치를 위해 다음 명령어를 터미널에 입력하자.
pip install selenium
추가적으로 셀레니움을 이용하면서 크롤링을 진행할때 편리한 webdriver_manager를 설치하자. 셀레니움을 사용하면 크롬 브라우저 버전이 업데이트 되면 그에 맞는 크롬 드라이버를 다운받아야하는 등 불편한 점들이 있었다. 이런 점들을 개선하기 위해 사용하는 라이브러리가 바로 webdriver_manager다. 설치 방법은 아래와 같다.
pip install webdriver_manager
간단히 크롬 브라우저를 통해 네이버 메인 홈페이지에 get 요청을 보내기 위해 아래와 같은 코드를 작성할 수 있다.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
chromeOptions = Options()
# 브라우저 꺼짐 방지
chromeOptions.add_experimental_option("detach", True)
# ChromeDriverManager를 통해 최신 버전의 크롬 브라우저를 자동으로 설치한다. 그리고 해당 서비스 객체를 만들어서 반환해준다.
service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chromeOptions)
# 웹 페이지 요청
driver.get("https://www.naver.com")
- 강의 및 다른 블로그에서 브라우저 꺼짐을 위해 add_experimental_option("detach", True)를 사용했지만 해당 코드는 잘 동작하지 않았다. 만약 꺼짐을 방지하고 싶다면 해당 코드 말고 driver.get 아래에 input()과 같은 코드를 작성하여 파이썬 코드가 끝나지 않도록하자.
추가적으로 네이버 로그인과 같이 어떤 내용을 입력하거나 버튼을 눌러야하는 경우 아래와 같이 코드를 작성해 웹 컨텐츠와 상호작용할 수 있다.
import time
import pyautogui
import pyperclip
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
# ChromeDriverManager를 통해 최신 버전의 크롬 브라우저를 자동으로 설치한다.
# 그리고 해당 서비스 객체를 만들어서 반환해준다.
service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
# 웹 페이지 요청
driver.get("https://nid.naver.com/nidlogin.login?mode=form&url=https://www.naver.com/")
driver.implicitly_wait(10)
id = driver.find_element(By.CSS_SELECTOR, "#id")
id.click()
pyperclip.copy("id")
pyautogui.hotkey("ctrl", "v")
time.sleep(2)
pw = driver.find_element(By.CSS_SELECTOR, "#pw")
pw.click()
pyperclip.copy("pw")
pyautogui.hotkey("ctrl", "v")
time.sleep(2)
login_btn = driver.find_element(By.CSS_SELECTOR, "#log\.login")
login_btn.click()
- driver.find_element(): 원하는 태그를 찾아준다.
- pyperclip: 복사/붙여넣기 클립보드 기능을 위한 파이썬 모듈
- pyautogui: 마우스와 키보드 제어를 도와주는 라이브러리
- pyautogui.hotkey("ctrl", "v"): 여러 키를 동시에 입력해야할 때 사용하는 함수
- driver.implicitly_wait(10): 웹 로딩이 완료되기 전에 id 부분을 클릭한다면 에러가 발생한다. 따라서 충분한 시간을 기다려 주기 위해 implicitly_wait() 메서드를 사용한다.
위 코드를 동작시키면 네이버에 로그인할 수 있다. 로그인이 필요한 서비스를 크롤링할 때에 해당 방법을 사용할 수 있다.
2. 네이버 쇼핑 상품 가져오기
위 내용을 반영해서 네이버의 쇼핑에서 아이폰 15 상품 몇 가지를 크롤링 후 결과를 csv 파일에 저장해봤다.
import csv
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
# 쇼핑 메뉴 선택, a태그를 가지고, nav와 shop 클래스를 가지는 태그를 찾는다.
driver.get("https://shopping.naver.com/home")
driver.implicitly_wait(10)
# 검색창 클릭
driver.find_element(By.CSS_SELECTOR, "._combineHeader_expansion_search_inner_1VxB3").click()
# 검색창 클릭 후 다음 화면으로 넘어가서 다시 검색창 클릭
search = driver.find_element(By.CSS_SELECTOR, "#input_text")
search.click()
search.send_keys("아이폰 15") # 검색어 입력
search.send_keys(Keys.ENTER) # 엔터 눌러줌
before_h = driver.execute_script("return window.scrollY")
# 가장 아래로 스크롤을 내림
while True:
# 키보드의 End 버튼을 누르면 스크롤이 계속 내려감
driver.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END)
# 스크롤 사이 페이지 로딩 시간
time.sleep(1)
current_h = driver.execute_script("return window.scrollY")
if current_h == before_h:
break
before_h = current_h
items = driver.find_elements(By.CSS_SELECTOR, ".product_info_main__piyRs")
file = open("result.csv", 'w', encoding="utf-8", newline='')
csvWriter = csv.writer(file)
for item in items:
name = item.find_element(By.CSS_SELECTOR, ".product_info_tit__c5_pb").text
try:
price = item.find_element(By.CSS_SELECTOR, ".product_num__iQsWh").text
except:
price = "판매 중지"
link = item.find_element(By.CSS_SELECTOR, ".product_info_main__piyRs > a").get_attribute("href")
csvWriter.writerow([name, price, link])
- 코드는 주석을 참고하자.
'DB > Crawling' 카테고리의 다른 글
6. word 활용 (python-docx) (0) | 2024.04.06 |
---|---|
5. 네이버 뉴스 본문 크롤링 (0) | 2024.04.06 |
3. Openpyxl 기본 개념 (네이버 주식 정보 수집) (0) | 2024.04.01 |
2. 네이버 뉴스 데이터 수집 (페이지 가져오기) (0) | 2024.04.01 |
1. 크롤링 기본 (Request, BeautifulSoup 소개 및 CSS 선택자) (0) | 2024.03.31 |