스마트한 개발 공부/Python

[Python] 파이썬 셀레니움(Selenium)을 사용한 간단한 네이버 크롤링

스마트한지노 2021. 6. 5. 15:38
728x90
반응형

Python에 있는 selenium이라는 라이브러리를 사용하여 크롤링을 하는 방법에 대해 알아보자.

import platform
import sys
import os
import pandas as pd

from bs4 import BeautifulSoup
from selenium import webdriver
import time

우선, 위에 있는 라이브러리들을 설치해준다.
라이브러리가 없다면 pip install **** 으로 없는 라이브러리를 설치해준다. 

path = "chromedriver.exe"

driver = webdriver.Chrome()

driver.get("http://naver.com")
time.sleep(2)

그리고, chrome을 웹브라우저로 사용할 것이기 때문에 chromedriver를 설치하고 naver를 시작페이지로 정해준다. (특정 웹사이트를 크롤링 하기 위해서는 각 사이트별로 코드가 따르기 때문에 범용적인 네이버로 한다)
chrome driver는 https://chromedriver.chromium.org/downloads 여기서 받으면 되는데 그냥 최신으로 받으시길!
해당 파일을 다운받은 다음에 python 코드를 실행하고 있는 폴더와 동일한 위치에 exe파일을 붙여넣으면 된다.

query_text = input("크롤링 할 맛집은? (형식 : **맛집) : ")

element = driver.find_element_by_id("query")

element.send_keys(query_text)
element.submit()
time.sleep(1)

저는  맛집을 크롤링 해볼건데, naver 검색창은 "input id"를 "query"로 받기 때문에 find_element_by_id에 query를 넣었다. 입력창으로 받은 데이터를 보내줬다. time.sleep은 가끔씩 너무 빠르게 통신을 받다보면 오류가 난다고 해서 각 작업마다 1초씩 delay를 주었다. 

이렇게 하면 입력창에 적은 내용이 검색창에 입력되고 검색이 된다.

driver.find_element_by_link_text("VIEW").click()
time.sleep(1)
driver.find_element_by_link_text("블로그").click()
time.sleep(1)
driver.find_element_by_link_text("옵션").click()
time.sleep(1)
driver.find_element_by_link_text("1개월").click()
time.sleep(1)

다음은 마우스로 클릭해서 다른 항목으로 이동하는 것을 구현한 것이다. 나는 element_by_link_text 를 사용해서 간단하게 들어갔지만, 이렇게 할 수 없는 웹사이트들도 있는데 이럴 때는 element_by_link_link로 href 값을 직접 넣어줘야 한다. VIEW을 보면 VIEW가 text로 들어가 있다. 다른 사이트에서도 이런식으로 찾으면 된다!!

위 코드처럼 입력하면 블로그 중에서 최근 1개월이내에 작성된 글들만 보인다. 여기 각 블로그별로 url과 글 제목을 가져오도록 해보겠다. 우선, 웹페이지에서 각 url에 저장된 자료를 가져온다. 

class_articles = ".api_txt_lines.total_tit"
url_link = driver.find_elements_by_css_selector(class_articles)

 


find_elements_by_css_selector함수는 웹페이지의 특정요소를 찾아서 데이터를 가져와준다. 근데, 여기에서 어려움을 겪을 수가 있다. (나도 그랬다...) 오류는 크게 2가지이다. 

  1. find_element_by_css_selector와 find_elements_by_css_selector의 함수 혼동
    - 앞의 함수는 1가지의 요소를 가져오는 것이고 뒤의 함수는 여러개의 값을 가져오기 때문에 데이터가 1개가 아니라면 elements를 쓴다.
  2. 그렇다면 어떤 값을 가져와야 할까?
    블로그를 크롤링할 것이기 때문에 블로그 상단을 개발자 도구로 보면 빨간 줄이 그어져 있는걸 볼 수 있다. 이부분을 복사해서 찾으면된다. class 항목에 해당 자료가 들어있는 것을 볼 수 있다. class에 있는 것을 그대로 복사해서 사용해도 되는데, 이럴 경우에 복사되는 값이 api_txt_lines total_tit 이런 식으로 나올 수도 있다. 띄워쓰기가 생기고 맨 앞에 .도 붙어있지 않다. 이러면 오류가 나니까 .api_txt_lines.total_tit 처럼 바꿔서 사용해야한다. 
url_list =[]
title_list = []

for article in url_link:
    url=article.get_attribute('href')
    url_list.append(url)

for article in url_link:
    title = article.text
    title_list.append(title)


url_link에는 많은 데이터들이 들어있다. 나는 여기서 url 링크와 블로그 제목만을 가져오려고 한다. 
먼저, url 링크 값과 제목을 저장해줄 list를 각각 만든다. 
get_attribute 함수는 요소 중에서 내가 지정하는 요소를 추출한다. 여기서 링크의 요소가 "href"이다. 
그리고 일반적으로 text는 웹페이지 상에서 보이는 text 내용으로 간주한다. 블로그 같은 경우는 접속 링크가 보통 제목이기 때문에 text로 바로 가져왔다. 

df = pd.DataFrame({'url' : url_list, 'title' : title_list})
df.to_excel("blog_url.xlsx")

이제 저장된 데이터들을 엑셀파일로 만들어보자. pd.DataFrame은 pandas에서 제공하는 dataframe을 만드는 방법인데 간편해서 이걸 사용했다. 데이터가 잘 들어갔다는 가정하에 위와 같이 코드를 작성하면 blog_url이 담겨있는 엑셀 파일이 만들어진다. 

728x90
반응형