📝동적 크롤링
동적인 데이터를 수집하는 방법을 말한다.
동적인 데이터란 입력, 클릭, 로그인 등과 같이 페이지 이동이 있어야 보이는 데이터를 말한다.
정적크롤링 수집하는 속도가 느리다는 단점이 있지만 더 많은 정보를 수집할 수 있다는 장점
셀레니움이라는 것을 사용하여 동적 크롤링하겠습니다.
일단 Chrome으로 진행해주시고 Chromdriver라는게 필요합니다.
https://sites.google.com/chromium.org/driver/downloads
여기에서 다운 받아주세요 버전은 최신 버전으로 다운 받아주세요
내가 쓰는 Chrome 버전하고 호환이 되어야합니다. 따로 확인하는 법은 잘 모르겠고 밑에 코드 돌려서 에러 나오면 버전이 안 맞다고 하니까 그 버전으로 바꿔주시면 되겠습니다.
# 본 프로그램은 동적인 웹페이지를 크롤링하는 프로그램입니다.
# 작성 시작일 2021. 04. 16
# 수정일 2023.06.14 Selenimum Version 변경으로 인한 수정
# 작성자 이성재
# Selenium.py
# Python 3.11 Selenium 4.1.0, Chrom Version 114
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service as ChromeService
import time
import urllib.request
# 크롬 열고 검색하기
path = "C://chromedriver/chromedriver.exe" # 웹 드라이버가 있는 경로
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
service = ChromeService(executable_path=path)
driver = webdriver.Chrome(service=service, options=options)
driver.get("https://www.google.co.kr/imghp?hl=ko") # 구글 이미지 메인 페이지
elem = driver.find_element(By.NAME, 'q') # driver.find_element_by_name("q") # 검색 부분에 name이 q이다
elem.send_keys("배우") # 검색하고자 하는 것
elem.send_keys(Keys.RETURN) # 엔터값 전송 크롤링이라는 글자를 입력하고 엔터를 누르는 과정
# 페이지 끝까지 스크롤 내리기
SCROLL_PAUSE_TIME = 1 # 대기시간을 1초로 셋팅
# 스크롤 깊이 측정하기 자바스크립트문을 실행시킴
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
# 스크롤 끝까지 내리기
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 페이지 로딩 기다리기
time.sleep(SCROLL_PAUSE_TIME)
# 더 보기 요소가 있을 경우 클릭하기
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
try:
driver.find_element(By.CSS_SELECTOR, '.mye4qd').click() # 더 보기에 css name이 mye4qd이다
except:
break
last_height = new_height
# 이미지를 찾고 , 다운받기
image_path = "c:/actor/" # 이미지 저장될 경로 설정
images_list = driver.find_elements(By.CSS_SELECTOR, '.rg_i.Q4LuWd') # driver.find_elements_by_css_selector(".rg_i.Q4LuWd")
# class 명이 rg_i Q4LuWd 이지만 .으로 구분하고 css가 2개 적용된 거임 # images_list는 배열이다 즉 여러개 이미지의 정보를 넣는다
count = 1
for image in images_list:
try :
image.click() # 크롬 브라우저에서 작은 이미지를 클릭하는 효과와 동일
time.sleep(2) # 2초 기다린다.
# f12을 사용하여 개발자모드에서 검사-> copy -> Copy Xpath를 해서 경로를 가지고 온다
imgUrl = driver.find_element(By.XPATH,"//*[@id=\"Sva75c\"]/div[2]/div/div[2]/div[2]/div[2]/c-wiz/div/div/div/div[3]/div[1]/a/img").get_attribute("src")
# "" 안에 " 기호를 쓰기위해 \ 로 감싸준다
# 이미지를 urllib.request를 사용하여 저장
# xpath 값 , 저장될 공간 + 크롤링(이름)
urllib.request.urlretrieve(imgUrl, image_path+"actor" + str(count) + ".jpg")
count = count + 1
except Exception as e:
print("이미지를 저장할 수 없습니다.")
print(e)
pass # 에러 발생시 무시하고 계속 진행
# 프로그램 종료
driver.close()
- path = "chromedriver/chromedriver.exe"
- 다운 받은 chromdriver 있는 경로를 설정해주세요 저는 이 .py있는 곳에 chromedriver라는 폴더에 넣어놨습니다.
- driver = webdriver.Chrome(path)
- 경로에 있는 chrome driver를 로드합니다
- driver.get("https://www.google.co.kr/imghp?hl=ko")
- driver.get("시작할 처음 주소")
- elem = driver.find_element_by_name("q")
- name = "q"라고 되어있는 검색 부분을 가져옵니다.
- elem.send_keys("배우")
- send_keys를 통해 driver가 "배우"라는 검색어를 입력하게 합니다.
- elem.send_keys(Keys.RETURN)
- Keys.RETURN이라고 넣어주면 엔터를 누르는 과정입니다.
- SCROLL_PAUSE_TIME = 1
- 스크롤 Pause 시간
- last_height = driver.execute_script("return document.body.scrollHeight")
- chromedriver한테 return document.body.scrollHeight 이러한 스크립트문을 하라고 명령합니다
- 스크롤바가 있을 때 그 깊이를 측정하는 과정입니다.
- driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
- 검색시 처음 나오는 화면이 0이고 document.body.scrollHeight(맨 밑)까지 스크롤바를 내리게 합니다.
- time.sleep(SCROLL_PAUSE_TIME)
- 대기시간을 1초를 주는 과정입니다.
코드는 엄청 빨리실행되는데 반해 검색해서 가려진 이미지들이 다 뜨는데 시간차이가 있기 때문에 그렇습니다.
# 더 보기 요소가 있을 경우 클릭하기
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
try:
driver.find_element(By.CSS_SELECTOR, '.mye4qd').click() # 더 보기에 css name이 mye4qd이다
except:
break
last_height = new_height
new_height에 다시 깊이를 잽니다 밑에 사진의 결과 더보기가 나올때까지 내려가야합니다.
📝동작과정 요약
- 먼저 현재 보이는 부분 깊이를 잽니다(last_height)
- 스크롤을 내립니다 (스크롤을 다 내리면 결과 더보기가 먼저 나오지 않고 로딩하면서 좀 더 사진이 나옵니다.)
- 거기에 보이는 부분 깊이를 잽니다 (new_height)
- new_height랑 last_height값은 다릅니다. 그 후 last_height에 new_height값을 넣어줍니다
- new_height는 끝에 도달하지 않는 이상 계속 갱신되니까 if문에 들어가지 않습니다.
- new_height 값과 last_height값이 같아진다는 거는 결과 더보기까지 내려갔다는 소리이니까 결과더보기에 해당하는 mye4qd라는 클래스를 가진 버튼을 클릭하게 합니다.
결과 더보기에 대한 class명입니다.
- images_list = driver.find_elements_by_css_selector(".rg_i.Q4LuWd")
- 이미지에 대한 요소를 저장하는 리스트를 만들어 넣습니다.
- 사진 class명을 보면 rg_i랑 Q4LuWd라는 클래스를 가집니다.
- image.click()
- 이미지를 클릭
📝Xpath
Xpath는 마크업 언어에서 특정 요소를 찾기 위한 경로(path)를 나타내는 언어입니다. 여기에선 이미지의 실질적 경로를 의미하죠
클릭했을때 나오는 사진을 검사를 눌러 나오는 태그에 오른쪽 클릭 후 Copy - Copy Xpath를 합시다.
driver.find_elements_by_xpath로 Xpath값을 넣습니다.
그냥 붙혀넣으면 빨간줄이 생기는데 왜 생기냐면 더블쿼테이션 안에 더블 쿼테이션이 들어가서 그렇습니다.
"를 그냥 문자로 인식하게 하려면 \" 이렇게 쓰면 됩니다 \"가 그냥 " 문자로 표현한다고 생각하면 됩니다.
실행시키면 C드라이브 actor라는 폴더에 이미지가 저장이 됩니다.
'[Big Data]' 카테고리의 다른 글
[BigData] 빅데이터 빈도분석을 WordCloud로 표현해보기 (0) | 2021.07.24 |
---|---|
[BigData] 빅데이터 코엔엘파이설치 및 Twitter (형태소 분리) (0) | 2021.07.23 |
[BigData] 빅데이터 Beautiful Soup 할리스매장 크롤링하기(CSV로 저장해보기) (0) | 2021.07.23 |
[BigData] 빅데이터 정적 크롤링(BeautifulSoup) (0) | 2021.07.23 |