Selenium을 이용한 Web 크롤링 개발

2023. 7. 2. 12:31Web 개발

크롤링

 

: 웹 페이지를 그대로 가져와서 거기서 데이터를 추출해 내는 행위

 

 

Selenium

 

: Selenium은 주로 웹앱을 테스트하는데 이용하는 프레임워크 

  webdriver라는 API를 통해 운영체제에 설치된 Chrome등의 브라우저를 제어 함

 

 

셀레늄 웹 드라이버(Selenium WebDriver)는 다양한 웹 브라우저와 다양한 운영 체제에서 시작된 웹 페이지를 테스트할 수 있는 웹 기반 자동화 테스트 프레임워크

 

크롤링 환경 구축

 

■  Selenium 패키지 설치

pip install selenium

 

참고: Selenium의 버전은 자주 업데이트 되고, 브라우저의 업데이트 마다 새로운 Driver를 잡아주기 때문에 항상 최신버전을 깔아 주는 것이 좋다.

 

 

■  Web Driver

 

WebDriver는 Selenium IDE와 달리 Firefox, Chrome뿐만 아니라 다른 브라우저에서 테스트를 실행할 수 있는 웹 자동화 프레임 워크이다

 

Selenium도 webdriver 통해 디바이스에 설치된 브라우저들을 제어할 수 있다

 

크롬을 사용하려면 로컬에 크롬이 설치되어있어야 한다.

 

+ 크롬 드라이버 다운로드 받기

https://sites.google.com/chromium.org/driver/?pli=1 

 

 

 

 

크롬 드라이버와 현재 사용중인 크롬의 버전을 맞춰야 Error 가 안 난다.

 

따라서, 크롬 URL에 chrome://version 을 입력하여 버전 확인

크롬 버전 : 114.0.5735.199

 

114.0.5735.90 버전의 크롬드라이버 설치

 

 

 

코드 작성

 

★  크롤링 Target

 

: https://m.boannews.com/html/news.html?mtype=1&tab_type=1 

보안 뉴스 페이지의 조회순 게시글의 제목, 링크, 내용을 크롤링하여 CSV파일로 변환하여라 !

 

 

■  필요한 클래스 import

from selenium import webdriver    
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pandas as pd

 

  • Selenium 패키지에서 webdriver, chrome.service, By 클래스들을 가져옴
  • (크롬 브라우저로 크롤링하기 위해 webdriver.chrome.service의 Service클래스가 필요함)
  •  
  • 마지막에 CSV파일로 변환하기 위해 필요한 pandas의 pd도 가져옴

 

 

■  Chrome WebDriver 설정

 service = Service(executable_path='C:/Users/alswh/Downloads/chromedriver_win32/chromedriver.exe')
 driver = webdriver.Chrome(service=service)
  • service 객체를 생성하여 Chrome WebDriver 서비스를 설정
  • executable_path 변수에 사용하고 있는 Chrome WebDriver의 경로를 입력
  • webdriver.Chrome() 생성자를 호출하여 WebDriver 객체를 생성

 

■  배열 선언

Title_list = []
Content_list = []

크롤링한 text 값을 저장할 배열을 선언함

Title_list = 제목

Link_list = 링크

Content_list = 내용

 

 

■  필요한 클래스 import

 

driver.get('https://m.boannews.com/html/Main_Menu.html?mkind=1') #Target URL에 접근


song_xpath_1 = driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[1]/a')
song_1 = song_xpath_1.text

Title_list.append(song_1)

조회순 첫번째 게시물의 제목 부분 XPATH를 가져와서

song_xpath_1 변수에 저장하고

song_1 변수에 song_xpath_1의 범위를 Text로 변환하여 저장하도록 하였다

 

그리고, Text로 변환된 값을 위에서 만들어둔 Title_list 배열에 추가해주었다

 

driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[1]/a').click()


song_xpath_2 = driver.find_element(By.XPATH,'//*[@id="con"]')
song_2 = song_xpath_2.text

Content_list.append(song_2)

.click으로 첫 게시글을 클릭하여 들어가고

 

song_xpath_2 변수에 글 내용의 xpath인 //*[@id="con"] 부분의 내용을 긁어오도록 저장하고

song_2 변수에서 그 값을 Text로 변환하여 저장하였다.

 

그리고 내용을 담는 배열인 Content에 text값을 추가하였다.

 

 

■  필요한 클래스 import


song_xpath_3 = driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[2]/a')
song_3 = song_xpath_3.text

Title_list.append(song_3)


driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[2]/a').click()


song_xpath_4 = driver.find_element(By.XPATH,'//*[@id="con"]')
song_4 = song_xpath_4.text

Content_list.append(song_4)

위의 코드는 두번째 게시글의 제목과 내용을 긁어 오는 코드이며

 

첫번째 게시글의 Xpath인 '/html/body/dl/dd[1]/section/ul[2]/li[1]/a'

에서  '/html/body/dl/dd[1]/section/ul[2]/li[2]/a' 로  뒤에 [1]이 [2]로 변한것 말곤 달라진점이 없기에

 

똑같이 진행하였다

 

(1~5개의 게시글 코드 작성 )

 

 

 

■  데이터프레임 및 CSV 변환

data = {"title":Title_list,"content":Content_list}
df = pd.DataFrame(data)

print(df.head(5))

df.to_csv("test.csv", encoding = "utf-8-sig")

 

마지막으로 CSV파일을 만들기 위해서

크롤링한 데이터를 판다스 데이터 프레임으로 우선 변환할것이다

 

data 딕셔너리에 크롤링한 데이터를 저장하였고

df변수에 pd.DataFrame()을 사용하여 데이터프레임으로 변환하였다

 

 

그리고 print (df.head(5))로 데이터프레임의 첫 5행을 출력하는 코드를 넣었고 

잘 출력 되면 데이터프레임까지 잘 이루어진것이다

 

마지막으로 df.to_csv("test.csv", encoding = "utf-8-sig"

를 통해서 test.csv이름으로 데이터들을 CSV파일로 변환시켰고 

UTF-8-sig로 인코딩시켜 한글깨짐을 없앴다

 

 

 

ERROR 모음
PermissionError: [Errno 13] Permission denied: 'test.csv' = 만들어진 test.csv파일을 열어놓은 상태로 크롤링을 다시 돌렸을때 나타나는 에러 (CSV파일 끄고 실행하면 에러 안 뜸) 

 

 

 

 

 

 

 

 

 

<crawling.py> - 전체 코드

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pandas as pd




service = Service(executable_path='C:/Users/alswh/Downloads/chromedriver_win32/chromedriver.exe')
driver = webdriver.Chrome(service=service)   # 크롬 드라이버 연결

driver.implicitly_wait(3) #웹 자원 로드를 위해 3초 기다려줌

Title_list = []
Content_list = []

######################################################   1번째 게시물


driver.get('https://m.boannews.com/html/Main_Menu.html?mkind=1') #Target URL에 접근


song_xpath_1 = driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[1]/a')
song_1 = song_xpath_1.text

Title_list.append(song_1)


driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[1]/a').click()


song_xpath_2 = driver.find_element(By.XPATH,'//*[@id="con"]')
song_2 = song_xpath_2.text

Content_list.append(song_2)

######################################################   2번째 게시물


driver.get('https://m.boannews.com/html/Main_Menu.html?mkind=1')

song_xpath_3 = driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[2]/a')
song_3 = song_xpath_3.text

Title_list.append(song_3)


driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[2]/a').click()


song_xpath_4 = driver.find_element(By.XPATH,'//*[@id="con"]')
song_4 = song_xpath_4.text

Content_list.append(song_4)


######################################################   3번째 게시물


driver.get('https://m.boannews.com/html/Main_Menu.html?mkind=1')

song_xpath_5 = driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[3]/a')
song_5 = song_xpath_5.text

Title_list.append(song_5)


driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[3]/a').click()


song_xpath_6 = driver.find_element(By.XPATH,'//*[@id="con"]')
song_6 = song_xpath_6.text

Content_list.append(song_6)


######################################################   4번째 게시물



driver.get('https://m.boannews.com/html/Main_Menu.html?mkind=1')

song_xpath_7 = driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[4]/a')
song_7 = song_xpath_7.text
Title_list.append(song_7)


driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[4]/a').click()


song_xpath_8 = driver.find_element(By.XPATH,'//*[@id="con"]')
song_8 = song_xpath_8.text

Content_list.append(song_8)

######################################################   5번째 게시물


driver.get('https://m.boannews.com/html/Main_Menu.html?mkind=1')

song_xpath_9 = driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[5]/a')
song_9 = song_xpath_9.text

Title_list.append(song_9)


driver.find_element(By.XPATH,'/html/body/dl/dd[1]/section/ul[2]/li[5]/a').click()


song_xpath_10 = driver.find_element(By.XPATH,'//*[@id="con"]')
song_10 = song_xpath_10.text

Content_list.append(song_10)


######################################################   판다스 데이터프레임으로 CSV파일 저장


data = {"title":Title_list,"content":Content_list}
df = pd.DataFrame(data)

print(df.head(5))

df.to_csv("test.csv", encoding = "utf-8-sig")

 

'Web 개발' 카테고리의 다른 글

로그인 & 회원가입 (Node.js + DB연동)  (0) 2023.07.20
CSS  (0) 2023.02.03
Node.js + MySQL 연동 / SQL injection 공격 실습  (0) 2023.01.30
JavaScript (자바스크립트)  (0) 2023.01.25
HTML 태그  (0) 2023.01.25