programming/Python

웹 크롤링으로 기초 데이터 수집하기_데이터마이닝 1탄

Jofresh 2023. 7. 1. 19:10
728x90
반응형

이번 데이터마이닝 강의에서는

 

웹 크롤링으로 데이터를 수집하고, 키워드를 추출하여, 키워드 간의 연관 관계를 분석하고 이 결과를 시각화 해보도록 하겠습니다. 

 

웹 크롤링으로 데이터 수집하기

'나무위키 최근 변경 페이지'의 텍스트 데이터를 크롤링으로 수집한 다음, 데이터 내에서 등장한 키워드의 출현 빈도를 분석해볼께요.

 

이를 통해 나무위키 페이지에서 가장 '핫한' 키워드가 무엇인지 분석할 수 있습니다.

 

웹 크롤링이란?
웹 페이지를 방문해서 페이지의 자료를 자동으로 수집하는 작업을 의미 합니다.
파이썬을 통해서 웹 크롤링을 진행하도록 할께요.

 

대상 페이지의 구조 살펴보기

크롤링을 위한 첫번째 단계는 인터넷 익스플로러, 크롬 등의 웹 브라우저를 실행하여 크롤링의 대상이 될 페이지 구조를 살펴보는 것 입니다. 먼저 웹 브라우저의 '개발자 도구'를 실행합니다.

 

아래는 '크롬'에서 개발자 도구를 실행하는 방법입니다.

(윈도우 단축키 : 컨트롤+쉬프트+ i / MAC : 커맨드+알트+i)

 

개발자 도구

 

크롤링할 데이터는 나무위키 '최근 변경내역' 페이지 https://namu.wiki/RecentChanges의 텍스트 데이터입니다.

먼저 페이지의 구조를 살펴봅시다.

 

최근 변경내역 - 나무위키

KBS,MBC,SBS 아나운서 문서와 기본 틀 통일 (직급 기재) / 되돌릴 시 명확한 이유 기재 부탁드립니다. (r125으로 되돌림)

namu.wiki

왼쪽 페이지 리스트는 현재 나무위키에서 문서 편집이 발생한 페이지들의 목록입니다. 우리는 이 페이지들의 텍스트 데이터를 수집해야합니다. 따라서 가장 먼저 해야 할 일은 페이지 리스트의 URL 정보를 수집하는 것입니다. 

 

개발자도구로 살펴보는 나무위키 최근 변경내역 페이지

 

개발 도구를 열어 왼쪽 상단의 마우스 포인터 모양 아이콘을 클릭하고 URL 정보를 확인하고 싶은 페이지의 링크 위로 마우스 포인터를 이동한 뒤 클릭 합니다.

 

클릭 후에는 아래 그림처럼 하늘색 박스로 표시된 <a href= ...> 태그를 찾습니다.

이 부분이 URL 정보를 의미합니다. 

위의 과정을 파이썬으로 자동화 하여 웹크롤러를 만들어 보겠습니다.

 

웹 크롤링 라이브러리 사용하기

파이썬에는 다양한 라이브러리로 웹크롤러를 만들 수 있습니다. 

대표적으로는 requests와 selenium이 있습니다. 두 라이브러리에 대해서는 몇 번 다뤘었는데요. 

 

가장 큰 차이점이라고 하면, requests는 특정 URL로 부터 HTML 문서를 가져오는 작업을 수행하는데, 이는 동적 로딩되는 페이지는 웹 크롤링이 불가능합니다. 이러한 단점을 해소하는 것이 selenium 라이브러리입니다. selenium 라이브러리는 자바스크립트로 동적 로딩되는 페이지도 크롤링이 가능합니다.

 

vscode를 실행하고, 터미널에서 아래 3개의 라이브러리를 설치해줍니다.

pip install selenium

pip install requests

pip install beautifulsoup

그리고 셀리니움 라이브러리를 이용하기 위해서는 '크롬드라이버'를 설치해주셔야 하는데요.

 

1. 아래 링크로 들어가서 현재 크롬 버전과 동일한 드라이버를 다운로드 해줍니다.

2. 압축을 해제 합니다.

3. 현재 작업중인 파이썬 코드 파일 위치와 동일한 곳으로 파일을 이동(복사) 해줍니다.

 

ChromeDriver - WebDriver for Chrome - Downloads

Current Releases If you are using Chrome version 115 or newer, please consult the Chrome for Testing availability dashboard. This page provides convenient JSON endpoints for specific ChromeDriver version downloading. For older version of Chrome, please see

chromedriver.chromium.org

크롬드라이버 위치는 내가 작업하는 파일과 동일한 곳에 위치시켜준다.

 

설치 과정을 모두 마쳤다면,

아래의 코드처럼 크롬드라이버의 실행 경로를 지정해주고 크롬드라이버를 이용하여 URL의 HTML 문서를 가져온 뒤,

셀레니엄 라이브러리를 활용해서 URL을 가져옵니다.

from selenium import webdriver
from bs4 import BeautifulSoup
import re

# brew 로 설치된 chromedriver의 path (Mac)
path = "/usr/local/bin/chromedriver"

# 윈도우용 크롬 웹드라이버 실행 경로 (Windows)
excutable_path = "chromedriver.exe"

# 크롤링할 사이트 주소를 정의합니다.
source_url = "https://namu.wiki/RecentChanges"

# 사이트의 html 구조에 기반하여 크롤링을 수행합니다.
# driver = webdriver.Chrome(path)  # for Mac
driver = webdriver.Chrome(executable_path=excutable_path)  # for Windows
driver.get(source_url)
req = driver.page_source
soup = BeautifulSoup(req, "html.parser")
contents_table = soup.find(name="table")
table_body = contents_table.find(name="tbody")
table_rows = table_body.find_all(name="tr")
# a태그의 href 속성을 리스트로 추출하여, 크롤링 할 페이지 리스트를 생성합니다.
page_url_base = "https://namu.wiki"
page_urls = []
for index in range(0, len(table_rows)):
    first_td = table_rows[index].find_all("td")[0]
    td_url = first_td.find_all("a")
    if len(td_url) > 0:
        page_url = page_url_base + td_url[0].get("href")
        if "png" not in page_url:
            page_urls.append(page_url)

# 중복 url을 제거합니다.
page_urls = list(set(page_urls))
for page in page_urls[:5]:
    print(page)

# 크롤링에 사용한 브라우저를 종료합니다.
driver.close()

#출력 결과

https://namu.wiki/w/%EC%9D%B4%EC%84%BC%EB%93%9C%EB%9D%BC
https://namu.wiki/w/%EC%B2%AD%EC%95%84%EA%B7%B8%EB%A3%B9
https://namu.wiki/w/%ED%95%9C%EA%B5%ADGM%20%EB%9D%BC%EB%B3%B4
https://namu.wiki/w/%EA%B2%BD%EC%9F%81
https://namu.wiki/w/%ED%8B%80:2021%EB%85%84%20%EC%84%B8%EA%B3%84%20%EC%98%81%ED%99%94%20%ED%9D%A5%ED%96%89%20%EC%88%9C%EC%9C%84

 

위의 코드는 개발자도구로 살펴본 HTML 구조에 기반하여 

 

table > tbody > tr > td > a 태그 순의 HTML 계층 구조를 좁혀나가는 과정입니다. 이 과정을 통해 목표 태그에 도달했을 때, 

get(href) 함수로 태그의 속성 정보를 추출합니다. get() 함수는 해당 태그가 가지고 있는 특정한 속성을 추출합니다.

 

table > tbody > tr > td > a 태그 순의 HTML 계층 구조를 좁혀나가는 과정을 이미지로 보면 이렇습니다. 테이블안에 티바디 안에 티알 안에 티디 안에 에이 태그안의 href를 가져옵니다.

 

*** 웹페이지 관리자 (위키 관리자)가 태그명을 변경할 수 있습니다. 외부 크롤링을 막기 위해 주기적으로 바꾸는 경우도 존재합니다. 시간이 꽤 지난뒤 위 코드를 실행하면 오류가 날 수 있습니다. 그럴 경우 태그명이 달라진게 없는지 개발자도구로 확인 한 뒤 해당 부분만 수정해주면 정상작동할 거에요.

 

예를 들어 table > tbody 였던 태그가 table > sbody로 변경될 수 있습니다(극단적인 예시입니다).

 

 

텍스트 정보 수집하기

이전과 마찬가지로 개발자 도구의 마우스 포인터 모양 아이콘을 클릭합니다.

그리고 문서의 '제목' 문서의 '카테고리'부분, 그리고 '본문' 부분을 클릭하여 HTML의 구조를 파악합니다. 문서 전체 내용은 'article'이라는 태그 안에 구성되어 있습니다(바뀔 수 있습니다. 그럴 경우 태그를 바꿔 줘야합니다!). 

 

제목은 'h1' 태그 , 카테고리 부분은 'ul' 태그 영역 안에 존재하며, 본문의 내용은 'wiki-paragraph'라는 클래스로 구성된 'div' 태그안에 위치하고 있습니다.

 

다음 코드는 최근 변경된 문서 중 한 페이지의 텍스트 정보를 크롤링한 것입니다.이전 단계와 다른 점은 get()함수 대신 text()함수를 사용하여 태그의 텍스트 정보만을 추출했다는 점입니다.

# driver = webdriver.Chrome(path)  # for Mac
driver = webdriver.Chrome(executable_path=excutable_path)  # for Windows
driver.get(page_urls[0])
req = driver.page_source
soup = BeautifulSoup(req, 'html.parser')
contents_table = soup.find(name="article")
title = contents_table.find_all('h1')[0]
category = contents_table.find_all('ul')[0]
content_paragraphs = contents_table.find_all(name="div", attrs={"class":"wiki-paragraph"})
content_corpus_list = []

for paragraphs in content_paragraphs:
    content_corpus_list.append(paragraphs.text)
content_corpus = "".join(content_corpus_list)

print(title.text)
print("\n")
print(category.text)
print("\n")
print(content_corpus)

# 크롤링에 사용한 브라우저를 종료합니다.
driver.close()

 

#출력결과

 

 

 

자 이렇게 나무위키 url을 크롤링하고, 해당 url에 접속 한 뒤 해당 나무위키 페이지의 정보를 추출하는 코드를 만들어보았습니다.

 

태그나 class 와 같은 것들은 자주 변경됩니다. 코드 오류가 날 경우 태그명이 변경되었는지 확인 한 뒤 태그를 변경해주시는 것이 좋습니다. 

 

 

 

 

 

728x90
반응형