[Python] 동적 크롤링 (3)
'코뮤니티 모각코' 활동에서의 학습 내용을 바탕으로 작성한 글입니다.
자세한 내용은 링크를 통해 확인하시기 바랍니다.
동적 크롤링 4
https://codemate.kr/@datasponge/동적-크롤링-4
동적 크롤링 4 by datasponge | 코드메이트
크롤링 대상 사이트 살펴보기 코뮤니티 카페에 접속해서 신규 회원 게시판의 내용 수집하기 ① 네이버 로그인 페이지 ✔ 로그인 절차 : 아이디 입력 -> 비밀번호 입력 -> 로그인 버튼 클릭 ✔ 네
codemate.kr
크롤링 대상 사이트 살펴보기
코뮤니티 카페에 접속해서 신규 회원 게시판의 내용 수집하기
① 네이버 로그인 페이지
✔ 로그인 절차 : 아이디 입력 -> 비밀번호 입력 -> 로그인 버튼 클릭
✔ 네이버는 자동화 소프트웨어를 막고 있어 send_keys 함수를 사용하기 어렵기 때문에 selenium의 execute_script 함수 사용
✔ execute_script 함수 : 입력받은 JavaScript 코드를 브라우저에서 실행시킴
driver.execute_script("JS 스크립트")
✔ 로그인 버튼의 태그
-> 태그 : button
-> class : btn_login
-> id : log.login
✔ selenium에서는 점(.)을 클래스로 여기기 때문에 선택자와 태그 조합에 log.login이라는 id를 사용할 수 없음
✔ 이 경우 find_element 함수에서 By.CSS_SELECTOR 대신 By.ID 사용
✔ By.ID
driver.find_element(By.ID, "id")
② 신규회원 게시판의 id
✔ 신규 회원 게시판 버튼의 태그와 선택자
-> id : menuLink90
③ 게시글의 XPath
✔ XPath : 웹 페이지의 구조 최상단부터 태그를 타고 들어가 해당 HTML 요소가 어디에 존재하는지를 나타내는 경로의 일종
✔ selenium의 find_element 함수의 By.XPATH를 통해 HTML 요소를 선택할 수 있음
✔ 첫 번째 게시물의 XPath : /html/body/div[1]/div/div[4]/table/tbody/tr[1]/td[1]/div[2]/div/a
④ 게시물의 태그
✔ 글 내용의 태그 및 선택자
-> 태그 : div
-> class : se-module, se-module-text
파이썬 코드 작성
① 라이브러리 import
# 라이브러리 import
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
② 네이버 로그인 페이지 접속
# 라이브러리 import
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
# 자동화된 크롬 창 실행
chrome_driver = ChromeDriverManager().install()
service = Service(chrome_driver)
driver = webdriver.Chrome(service=service)
# 네이버 로그인 페이지 접속
login_url = 'https://nid.naver.com/nidlogin.login'
driver.get(login_url)
# 시간적 여유 원하는 만큼
time.sleep(2)
③ 아이디 & 비밀번호 입력
#...
# 본인의 아이디, 비밀번호를 각각 변수에 저장
# ex) 아이디 : datasponge, 비밀번호 : 11111
my_id = 'datasponge'
my_pw = '11111'
# 아이디와 비밀번호 입력
driver.execute_script("document.getElementsByName('id')[0].value = \\'" + my_id + "\\'")
driver.execute_script("document.getElementsByName('pw')[0].value = \\'" + my_pw + "\\'")
# 시간적 여유 원하는 만큼
time.sleep(1)
-> execute_script 함수에 적어둔 document.~~ 는 자바스크립트의 문법
④ 로그인 버튼 클릭
#...
# '로그인' 버튼 클릭
button = driver.find_element(By.ID, 'log.login')
button.click()
# 시간적 여유 원하는 만큼
time.sleep(1)
⑤ 코뮤니티 접속
#...
# 코뮤니티 접속
comu_url = 'https://cafe.naver.com/codeuniv'
driver.get(comu_url)
# 시간적 여유 원하는 만큼
time.sleep(1)
⑥ '신규회원게시판' 클릭
#...
# '신규회원게시판' 클릭
menu = driver.find_element(By.ID, 'menuLink90')
menu.click()
# 시간적 여유 원하는 만큼
time.sleep(1)
⑦ 프레임 전환
✔ 분명히 원하는 정보가 모두 화면에 있고 HTML 코드에서도 원하는 정보가 모두 있는데 파이썬으로 검색하면 없거나 크롤링이 되지 않는 경우, 프레임으로 구성된 부분이 있는지 확인해야 함
✔ 프레임은 HTML 내부에 또다른 HTML을 집어넣어 둔 것으로 생각하면 됨
✔ 프레임으로 구성된 웹 페이지를 크롤링하기 위해서는 selenium의 탐색 위치를 프레임 내부로 전환해줘야 함
개발자 도구에서 iframe 검색
-> 32개가 검색됨
-> 네이버 카페는 프레임으로 구성된 웹 페이지임을 알 수 있음
엔터키를 계속 누르다보면 우리가 원하는 정보가 포함된 파란 네모창이 나타남
-> 14번째의 iframe이 게시판을 나타냄
switch_to.frame 함수 : selenium의 탐색 위치를 프레임 내부로 전환해주는 함수
driver.switch_to.frame("프레임의 이름")
프레임 전환
#...
# 프레임 전환
driver.switch_to.frame('cafe_main')
# 시간적 여유 원하는 만큼
time.sleep(1)
⑧ 첫 번째 게시물 클릭
#...
# 첫 번째 게시물의 XPath
xpath = "/html/body/div[1]/div/div[4]/table/tbody/tr[1]/td[1]/div[2]/div/a"
# 첫번째 글 클릭
writing = driver.find_element(By.XPATH, xpath)
writing.click()
# 시간적 여유 원하는 만큼
time.sleep(1)
⑨ 글 내용 출력
#...
# 글 내용 출력
content = driver.find_element(By.CSS_SELECTOR, "div.se-component-content").text
print(content)
# 크롬 창 닫기
driver.close()
최종 코드
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
chrome_driver = ChromeDriverManager().install()
service = Service(chrome_driver)
driver = webdriver.Chrome(service=service)
login_url = "https://nid.naver.com/nidlogin.login"
driver.get(login_url)
time.sleep(2)
my_id = "datasponge"
my_pw = "11111"
driver.execute_script("document.getElementsByName('id')[0].value = '" + my_id + "'")
driver.execute_script("document.getElementsByName('pw')[0].value = '" + my_pw + "'")
time.sleep(1)
button = driver.find_element(By.ID, "log.login")
button.click()
time.sleep(1)
comu_url = "https://cafe.naver.com/codeuniv"
driver.get(comu_url)
time.sleep(1)
menu = driver.find_element(By.ID, "menuLink90")
menu.click()
time.sleep(1)
driver.switch_to.frame("cafe_main")
time.sleep(1)
xpath = "/html/body/div[1]/div/div[4]/table/tbody/tr[1]/td[1]/div[2]/div/a"
writing = driver.find_element(By.XPATH, xpath)
writing.click()
time.sleep(1)
content = driver.find_element(By.CSS_SELECTOR, "div.se-component-content").text
print(content)
driver.close()
동적 크롤링 5
https://codemate.kr/@datasponge/동적-크롤링-5
동적 크롤링 5 by datasponge | 코드메이트
코뮤니티 카페 - 신규 회원 게시판 < XPath > ✔ id, class에 구애받지 않고 크롤링을 진행할 수 있음 ✔ HTML 요소들의 패턴을 파악하기 쉬움 < XPath의 패턴 > 첫 번째 게시글의 XPath : /html/body/div[1]/div/div
codemate.kr
코뮤니티 카페 - 신규 회원 게시판
< XPath >
✔ id, class에 구애받지 않고 크롤링을 진행할 수 있음
✔ HTML 요소들의 패턴을 파악하기 쉬움
< XPath의 패턴 >
첫 번째 게시글의 XPath : /html/body/div[1]/div/div[4]/table/tbody/tr[1]/td[1]/div[2]/div/a
두 번째 게시글의 XPath : /html/body/div[1]/div/div[4]/table/tbody/tr[2]/td[1]/div[2]/div/a
세 번째 게시글의 XPath : /html/body/div[1]/div/div[4]/table/tbody/tr[3]/td[1]/div[2]/div/a
< 파이썬 코드 구현 >
① 지난 시간의 코드
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
chrome_driver = ChromeDriverManager().install()
service = Service(chrome_driver)
driver = webdriver.Chrome(service=service)
login_url = "https://nid.naver.com/nidlogin.login"
driver.get(login_url)
time.sleep(2)
my_id = "ID"
my_pw = "PW"
driver.execute_script("document.getElementsByName('id')[0].value = '" + my_id + "'")
driver.execute_script("document.getElementsByName('pw')[0].value = '" + my_pw + "'")
time.sleep(2)
button = driver.find_element(By.ID, "log.login")
button.click()
time.sleep(2)
comu_url = "https://cafe.naver.com/codeuniv"
driver.get(comu_url)
time.sleep(2)
menu = driver.find_element(By.ID, "menuLink90")
menu.click()
time.sleep(2)
driver.switch_to.frame("cafe_main")
time.sleep(2)
xpath = "/html/body/div[1]/div/div[4]/table/tbody/tr[1]/td[1]/div[2]/div/a"
writing = driver.find_element(By.XPATH, xpath)
writing.click()
time.sleep(2)
content = driver.find_element(By.CSS_SELECTOR, "div.se-component-content").text
print(content)
driver.close()
② 뒤로 가기
✔ 순서 : 로그인 - 게시판 이동 - 게시글 진입 - 내용추출 - 뒤로가기 - 게시글 진입 - ...
✔ back 함수 : 뒤로 가기 구현
driver.back()
적용
#...
# 뒤로 가기
driver.back()
time.sleep(1)
driver.close()
③ XPath 패턴을 사용해 반복문 구현
✔ 네이버 카페는 프레임으로 구성되어 있어 기본 크롤링 방식으로는 검색이 되지 않음
✔ 페이지를 이동할 때마다 selenium의 탐색 범위가 초기화됨
✔ 반복문 내부에 switch_to.frame 함수를 넣어 게시판으로 돌아갈 때마다 selenium의 탐색 범위를 cafe_main으로 변경해줘야 함
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
chrome_driver = ChromeDriverManager().install()
service = Service(chrome_driver)
driver = webdriver.Chrome(service=service)
login_url = "https://nid.naver.com/nidlogin.login"
driver.get(login_url)
time.sleep(2)
my_id = "ID" # 본인 아이디
my_pw = "PW" # 본인 비밀번호
driver.execute_script("document.getElementsByName('id')[0].value = '" + my_id + "'")
driver.execute_script("document.getElementsByName('pw')[0].value = '" + my_pw + "'")
time.sleep(2)
button = driver.find_element(By.ID, "log.login")
button.click()
time.sleep(2)
comu_url = "https://cafe.naver.com/codeuniv"
driver.get(comu_url)
time.sleep(2)
menu = driver.find_element(By.ID, "menuLink90")
menu.click()
time.sleep(2)
# 반복문 구현
for i in range(1,11):
xpath=(
"/html/body/div[1]/div/div[4]/table/tbody/tr["+str(i)+"]/td[1]/div[2]/div/a"
)
driver.switch_to.frame("cafe_main")
time.sleep(2)
writing = driver.find_element(By.XPATH, xpath)
writing.click()
time.sleep(2)
content = driver.find_element(By.CSS_SELECTOR, "div.se-component-content").text
print(content)
driver.back()
time.sleep(1)
driver.close()
> 실행결과