코뮤니티 모각코

[Python] 동적 크롤링 (3)

넝구리 2022. 4. 18. 13:33

'코뮤니티 모각코' 활동에서의 학습 내용을 바탕으로 작성한 글입니다.

자세한 내용은 링크를 통해 확인하시기 바랍니다.


동적 크롤링 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()

> 실행결과