웹 크롤링 - 7. 특정 웹 페이지 태그를 워드 클라우드로 시각화

·2023년 4월 21일
0

웹크롤링

목록 보기
7/7
post-custom-banner

🔎 word cloud를 이용해 특정 페이지의 태그를 스크래핑 한 후 빈도 수가 잦은 태그 이름을 워드 클라우드로 시각화해 보자


1. 스크래핑 할 웹 페이지 요소 분석

  • 우리는 이 웹 페이지에서 주제 태그를 추출해야 한다.
  • 그리고주제들이 각각 몇 번이나 세어 그래프로 시각화해 주어야 한다.
  • 그러기 위해서 저 태그 부분을 우 클릭 후 검사를 눌러 위치를 확인해 준다.
  • 구조를 보면 class namequestion-tagsul 태그 내부에 li 태그 안에 우리가 추출하여야 할 태그명이 존재한다는 것을 알 수 있다.
  • 그렇다면 class namequestion-tagsul 태그를 모두 찾은 후 li 태그 요소흫 모두 찾고 그 안에 있는 값의 context를 구하면 된다.

2. 찾아야 할 요소 스크래핑

  • 스크래핑을 하기 위한 라이브러리를 호출해 준다.
  • 해당 페이지는 정적인 페이지이기 때문에 requests 라이브러리를 사용해 응답을 받고 Beautiful Soup 라이브러리를 사용해 HTML 파싱을 해 준다.
  • 이전 포스트에서는 10 페이지까지만 태그를 추출했는데 word cloud를 좀 더 꽉 차게 만들기 위해 이번에는 30 페이지까지 추출해 준다.
  • 또한 태그 이름 문자열을 저장해 주기 위한 리스트(list)를 만들어 태그 이름append 해 준다. (dictionary를 사용하지 않는 이유는 어차피 형태소를 분석해 주는 라이브러리를 통해 명사인 값만 추출해 주어야 하기 때문이다.)
user_agent = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"}

from bs4 import BeautifulSoup
import requests

questions = []

for i in range(1, 30):
    res = requests.get("https://qna.programmers.co.kr/?page={}".format(i), user_agent)  #페이지네이션 적용
    soup = BeautifulSoup(res.text, "html.parser")

    ul_tags = soup.find_all("ul", "question-tags")
    for ul in ul_tags:
        li_tags = ul.find_all("li")
        for li in li_tags:
            questions.append(li.text.strip())  #빈칸이 이상할 정도로 많다. strip()으로 처리
    time.sleep(0.5)

3. 텍스트 구름으로 만들기 위한 데이터 가공

  • word cloud로 만들기 위해서는 문장에서 명사를 추출하는 형태소 분석 라이브러리 konlpy을 호출해야 한다.
  • 또한 그 명사들이 총 몇 번이나 사용되는지의 빈도 수를 파악하기 위한 collections 라이브러리의 Counter도 호출해 주어야 한다.
  • Hannanum의 객체를 생성해 주고 2의 과정에서 만들어진 questions의 경우 리스트이기 때문에 for문을 돌며 리스트의 원소인 문자열이 명사인지 아닌지를 .nouns() 함수를 통해 확인해 주어야 한다.
  • 이후 명사일 경우 새로 만든 리스트에 추가해 준다.
  • 새로 만든 리스트는 명사만을 추출한 리스트이므로 이를 Counter로 변환해 주어야 텍스트 구름으로 시각화가 가능하다.
# 횟수를 기반으로 딕셔너리 생성
from collections import Counter

# 문장에서 명사를 추출하는 형태소 분석 라이브러리
from konlpy.tag import Hannanum

words = []
hannanum = Hannanum()
#문장이 아니라 지금은 리스트이기 때문에 for문을 돌면서 각각의 형태소를 분석해야 한다.
for question in questions:
    nouns = hannanum.nouns(question)  #한 번 반복할 때 나오는 명사들
    words += nouns #word에 누적해서 쌓아 둔다.
    
# counter를 이용해 각 단어의 개수를 세줍니다.
counter = Counter(words)
counter   

4. 텍스트 구름으로 시각화

  • word cloud로 만들어 주기 위해서는 wordcloud 라이브러리를 호출해 주어야 한다.
  • 또한 생성된 word cloud는 이미지 형식이기 때문에 이를 표출해 줄 matplotlib.pyplot 라이브러리도 호출해 준다.
  • wordcloud 객체를 만들어서 폰트 위치(한글을 지원하는 폰트로), height, width 등을 설정해 준다.
  • 이후 .generate_from_frequencies(counter)을 호출해 준다. (counter와 같이 key를 보여 줘야 하는 단어, value를 빈도 수로 가지는 구조의 변수를 word cloud로 변환해 주는 함수이다.)
# 시각화에 쓰이는 라이브러리
import matplotlib.pyplot as plt
from wordcloud import WordCloud

wordcloud = WordCloud(
    font_path = "/Users/Samsung/AppData/Local/Microsoft/Windows/Fonts/BMEULJIROTTF.ttf",
    height = 1000,
    width=1000
)

img = wordcloud.generate_from_frequencies(counter)
plt.imshow(img)

결과 값

profile
송의 개발 LOG
post-custom-banner

0개의 댓글