일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- coursera
- Tensor
- 웹스크래핑
- 웹크롤링
- 협업 필터링
- SGD
- recommendation system
- 코테
- 데이터
- codingtest
- pytorch
- 프로그래머스
- wordcloud
- Overfitting
- 분산 시스템
- 추천시스템
- 데이터 엔지니어링
- 파이썬
- 코딩테스트
- 부스트캠프
- 알고리즘
- 딥러닝
- selenium
- 머신러닝
- 백준
- Cosine-similarity
- Python
- 추천 시스템
- 시각화
- TF-IDF
- Today
- Total
개발자식
[크롤링] Selenium_구글 번역기 본문
Selenium을 이용하여 기사 본문에 자주 나온 단어를 구글 번역기 웹 크롤링을 통해 영어로 번역하여 가져오고, 이를 워드클라우드로 시각화한다.
part3의 전체 모든 내용을 알아야한다.
1. Selenium (셀레니움)
웹 크롤링을 하다 보면 여러 가지 아래와 같은 어려운 상황을 마주치게 된다.
- 해당 웹사이트가 프로그램을 통한 접근을 허용하지 않는 경우
- 해당 웹사이트가 로그인을 요구하는 경우
- 해당 웹사이트가 동적 웹페이지로 구성되어 있는 경우
이러한 경우 requests 라이브러리로만 해결하기 어려워 이런 상황을 해결하는 가장 효과적인 방법이 selenium을 이용하는 것이다.
selenium : 웹 사이트 테스트를 위한 도구로 브라우저 동작을 자동화할 수 있다.
설치 (주피터에서) :
!pip install selenium==4.1.0
!pip install webdriver-manager==3.5.2
from webdriver_manager.chrome import ChromeDriverManager # 자동으로 크롬드라이버(가상브라우저) 파일을 다운로드해주는 라이브러리
from selenium.webdriver.chrome.service import Service # 다운로드된 크롬드라이버 파일을 연결하기 위해 활용
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time
import pandas as pd
import warnings
warnings.filterwarnings("ignore") # 불필요한 Warning 메시지를 꺼줍니다.
브라우저 창 띄우기
# 자동으로 크롬드라이버(가상브라우저) 파일을 다운로드 후 세팅
service = Service(executable_path=ChromeDriverManager().install())
# 세팅된 크롬드라이버를 연결해 가상브라우저 실행
driver = webdriver.Chrome(service=service)
아래와 같은 창이 하나 뜬다.
웹 페이지 접근하기
translate_url = 'https://translate.google.co.kr/?sl=auto&tl=en&op=translate&hl=ko'
# hl=ko : Korean & tl=en : English
driver.get(translate_url)
브라우저 확인 :
- 웹 서버는 우리가 사람(브라우저)인 것처럼 판단하여 웹사이트에 접근할 수 있다.
앞으로 코드를 작성하는 창, 크롤링에 활용할 해당 url 창, 가상 브라우저 창 이렇게 세 개의 창을 열어두고 진행한다.
가상 브라우저창은 개발자 도구 열기, 버튼 클릭을 하지 않는다.
2. Selenium을 이용하여 문장 번역 & 크롤링
특정 element를 가져오기 위해 기존에 웹 크롤링 방식처럼 html를 통해 가져올 수 있다.
이는 계속 코드를 명시적으로 해줘야 하고, 가독성도 떨어지며 코드가 길어지게 된다.
그래서 selenium에서는 xpath와 같은 path language를 통해서도 명시적으로 element를 가져올 수 있게 했다.
번역할 문장 입력 공간 xpath 가져오기
origin_xpath = '/html/body/c-wiz/div/div[2]/c-wiz/div[2]/c-wiz/div[1]/div[2]/div[3]/c-wiz[1]/span/span/div/textarea'
driver.find_element_by_xpath(origin_xpath).send_keys('파이썬은 쉽습니다') # 기존 방식, XPath & Send_keys
- find_element_by : 조건에 일치하는 가장 첫 번째 요소를 반환 (find)
- find_elements_by : 조건에 일치하는 모든 요소를 list 형태로 반환 (find_all)
- send_keys : 현재 커서가 위치하는 곳에 넣는다.
그 외
- find_elements_by_tag_name
- find_elements_by_xpath
- find_elements_by_id
- find_elements_by_class_name
- find_elements_by_link_text
- find_elements_by_partial_link_text
- find_elements_by_css_selector
결과 :
번역된 데이터를 가져오기 위해 위와 같은 방식으로 XPath를 복사한다.
번역된 데이터를 가져온다.
translation_xpath = '/html/body/c-wiz/div/div[2]/c-wiz/div[2]/c-wiz/div[1]/div[2]/div[3]/c-wiz[2]/div[6]/div/div[1]/span[1]/span/span'
translated_contents = driver.find_element_by_xpath(translation_xpath) # XPath
print(translated_contents.text)
결과 :
Python is easy
3. Selenium을 활용하여 기사글 번역 & 크롤링
part 3-4에서 진행했던 네이버 기사 크롤링 데이터를 활용하여 본문을 번역해보자
df = pd.read_excel('result_220202_1834.xlsx')
df.head()
결과 :
article = df['Article'][0]
origin_xpath = '/html/body/c-wiz/div/div[2]/c-wiz/div[2]/c-wiz/div[1]/div[2]/div[3]/c-wiz[1]/span/span/div/textarea'
driver.find_element_by_xpath(origin_xpath).clear() # 깔끔하게 비우기(clear)
driver.find_element_by_xpath(origin_xpath).send_keys(article)
time.sleep(3)
translation_xpath = '/html/body/c-wiz/div/div[2]/c-wiz/div[2]/c-wiz/div[1]/div[2]/div[3]/c-wiz[2]/div[6]/div/div[1]/span[1]/span/span'
translated_contents = driver.find_element_by_xpath(translation_xpath).text
print('기사글 [ {} ] 의 번역이 끝났습니다.'.format(df['Title'][0]))
print(translated_contents)
- clear()로 번역할 문장에 남아있는 내용을 비워준다.
- 번역하는데 시간이 걸리기 때문에 time.sleep(3)으로 3초 후 번역된 문장 불러오는 코드를 실행한다.
결과 :
가상 브라우저 끄기
driver.close()
driver.quit()
- 직접 가상 브라우저 창을 닫아 끄지 않고 위 명령어를 진행한다.
기사 본문 내용에서 빈도가 높은 순으로 상위 100개의 단어를 워드크라우드 시각화를 해보자
기사 본문 내용 모두 번역한 후 빈도를 카운트해줘야 하나? 이는 굉장히 오래 걸리고 여러 개 요청을 보낼 때 밀릴 수 있다.
전체를 번역하지 않고 단어 카운트를 하고 그 단어를 번역한 후 시각화를 진행하자!!
4. 기사 본문 내용 상위 항목만 단어로 가져와 번역한다.
from collections import Counter
from konlpy.tag import Okt
articles = df['Article'].tolist()
articles = ''.join(articles)
tokenizer = Okt()
raw_pos_tagged = tokenizer.pos(articles, norm=True, stem=True)
del_list = ['하다', '있다', '되다', '이다', '돼다', '않다', '그렇다', '아니다', '이렇다', '그렇다', '어떻다']
word_cleaned = []
for word in raw_pos_tagged:
if not word[1] in ["Josa", "Eomi", "Punctuation", "Foreign"]: # Foreign == ”, “ 와 같이 제외되어야할 항목들
if (len(word[0]) != 1) & (word[0] not in del_list): # 한 글자로 이뤄진 단어들을 제외 & 원치 않는 단어들을 제외
word_cleaned.append(word[0])
word_counted = Counter(word_cleaned)
word_dic = dict(word_counted)
sorted_word_dic = sorted(word_dic.items(), key=lambda x:x[1], reverse=True)
translation_target = sorted_word_dic[:100]
상위 100번째의 단어 개수는 24개이다. 단어 개수가 24개 이상인 단어만 dict에 넣는다.
translation_target = {}
for key in word_dic:
if word_dic[key] >= 24: # 위에서 확인한 빈도수를 기반으로 번역 대상 단어를 선정합니다.
translation_target[key] = word_dic[key]
translation_result = {}
service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
translate_url = 'https://translate.google.co.kr/?sl=auto&tl=en&op=translate&hl=ko'
driver.get(translate_url)
print(driver.current_url)
time.sleep(3)
for key in translation_target: # 상위 100번째 빈도수에 해당하는 단어까지 담겨있는 dict
origin_xpath = '/html/body/c-wiz/div/div[2]/c-wiz/div[2]/c-wiz/div[1]/div[2]/div[3]/c-wiz[1]/span/span/div/textarea'
driver.find_element_by_xpath(origin_xpath).clear()
driver.find_element_by_xpath(origin_xpath).send_keys(key)
time.sleep(3) # 네트워크의 속도에 따라 잠깐씩 쉬어주면서 진행합니다.
translated_xpath = '/html/body/c-wiz/div/div[2]/c-wiz/div[2]/c-wiz/div[1]/div[2]/div[3]/c-wiz[2]/div[6]/div/div[1]/span[1]/span/span'
translated_contents = driver.find_element_by_xpath(translated_xpath).text
translation_result[translated_contents] = translation_target[key] # 번역이 완료된 단어 dict의 value로 기존 dict의 value를 꽂아줍니다.
print('단어 {}의 번역 완료 : {}'.format(key, translated_contents))
print('전체 번역이 끝났습니다!')
driver.close()
driver.quit()
[ NoSuchElementException (no such element: Unable to locate element) ] 에러가 발생하면, 네트워크 속도 등의 이슈로 인해 3초라는 사전에 설정된 시간 동안 기다렸으나 번역 결과가 아직 생성되지 않은 것입니다. (HTML Tag가 로딩되지 않음)
-> time.sleep(3)에서 3을 5~7으로 증가시켜주면 보다 안정적으로 결과를 받아올 수 있습니다.
가상 브라우저 결과 :
결과를 보면 번역이 잘못되는 경우가 있다.
잘못 번역된 단어는 수정하고 오역은 삭제한다.
translation_result['AI'] = translation_result['TO THE'] # AI
translation_result['go'] = translation_result['good morning my love'] # 가다
translation_result['KT'] = translation_result['CT.'] # KT
translation_result['LG'] = translation_result['LG.'] # LG
translation_result['Bitcoin'] = translation_result['Bit coin'] # 비트코인
del translation_result['TO THE']
del translation_result['good morning my love']
del translation_result['CT.']
del translation_result['LG.']
del translation_result['Bit coin']
5. 영어로 번역된 단어를 워드클라우드로 시각화한다.
from PIL import Image
from wordcloud import WordCloud, ImageColorGenerator # Image 로부터 Color 를 생성(Generate)해내는 객체입니다.
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
python_coloring = np.array(Image.open("python_mask.jpg"))
image_colors = ImageColorGenerator(python_coloring)
word_cloud = WordCloud(font_path="C:/Windows/Fonts/malgun.ttf", # font_path="C:/Windows/Fonts/NanumSquareB.ttf"
width=2000, height=1000,
mask=python_coloring,
background_color='white').generate_from_frequencies(translation_result)
plt.figure(figsize=(15,15))
plt.imshow(word_cloud.recolor(color_func=image_colors), interpolation='bilinear') # 다시(re) 색칠하기
# plt.imshow(word_cloud.recolor(colormap='Blues'), interpolation='bilinear') # Matplotlib colormap 활용 (http://j.mp/32UXOQ6)
plt.axis("off")
plt.tight_layout(pad=0)
plt.show()
결과 :
'Data > Python' 카테고리의 다른 글
[크롤링] BeautifulSoup, Wadis 마감 상품 재고 체크 & 메일 발송 크롤링 (0) | 2022.03.30 |
---|---|
[크롤링] Selenium_파파고 (1) | 2022.03.29 |
[스크래핑] Web scraping for news articles (3) (0) | 2022.03.29 |
[스크래핑] Web scraping for news articles (2) (0) | 2022.03.28 |
[스크래핑] Web scraping for news articles (1) (0) | 2022.03.28 |