728x90

Review
참고 포스팅 : 2020/05/23 - [Python Programming/Using Packages] - [데이터크롤링] 데이터크롤링을 위해 HTML 이해하기

[데이터크롤링] 데이터크롤링을 위해 HTML 이해하기

안녕하십니까, 간토끼입니다. 파이썬 관련 첫 포스팅입니다. (사실 파이썬은 자신없지만) 데이터크롤링 시리즈는 약 5번에 걸쳐 게시될 예정입니다. 1. 데이터크롤링 데이터크롤링, 혹은 스크래�

datalabbit.tistory.com


안녕하십니까, 간토끼입니다.

저번 포스팅에서는 데이터 크롤링을 위해 HTML이 무엇인지 간단하게 살펴보고, 선택자를 탐색하는 방법에 대해서 다뤘습니다.

이번 포스팅에서는 파이썬 패키지를 이용해 직접 데이터를 수집해보겠습니다.

파이썬의 대표적인 패키지입니다.


1. 패키지 이해하기 : Requests, BeautifulSoup
우리가 웹페이지에서 데이터를 크롤링하기 위해서는 크게 두 가지 작업을 필수적으로 해야합니다.

먼저 가져오고자 하는 데이터가 담긴 웹사이트를 파이썬을 통해 요청하는 것입니다.
즉 웹사이트 url을 인식시킴으로써 데이터를 요청하고, 요청한 데이터를 받아 활용할 수 있도록 합니다.
이를 위해 필요한 패키지를 Requests라고 합니다.

Requests를 이용해 웹페이지의 데이터를 요청했다면 웹사이트를 구성하고 있는 HTML 소스 코드를 가져올 수 있습니다.
그러나 컴퓨터는 이 코드가 HTML 코드인지 제대로 인식하지 못해 원하는 정보를 추출할 수 없게 됩니다.
이를 위해 필요한 것이 BeautifulSoup이며, HTML코드를 인식시켜 원하는 데이터를 선택하고 수집할 수 있게 하는 것을 파싱(Parsing)이라고 합니다.
즉, BeautifulSoup은 파싱을 할 수 있도록 도와주는 패키지입니다.

위 패키지는 파이썬에 내장된 패키지가 아니므로, 설치하지 않으셨다면 우선 설치를 하셔야 합니다.
파이썬 명령 프롬프트 창을 켜고 pip를 이용해 설치합니다.

# requests 설치하기
pip install requests

# BeautifulSoup 설치하기
pip install BeautifulSoup

저는 아나콘다를 사용하므로, 아나콘다를 사용하시는 분들은 Anaconda Prompt를 실행하여 설치하시면 되고,
파이참을 사용하시는 분들은 파이참 하단의 Terminal을 이용하여 위 명령어를 입력해주면 됩니다.

2. 패키지를 이용해 데이터 수집하기
위 패키지를 이용하여 위 데이터를 직접 수집해보겠습니다.

# 패키지 import하기
import requests
from bs4 import BeautifulSoup

# 1. 웹에서 데이터 가져오기 : 네이버TV 사이트
raw = requests.get("https://tv.naver.com/r")

# 2. 웹사이트의 HTML 소스코드 Parsing
html = BeautifulSoup(raw.text, "html.parser")

requests.get 함수를 이용하여 내가 수집하고자 하는 웹사이트를 가져오는데, raw.text는 내가 get한 웹사이트주소(raw)의 html 소스코드를 담은 문자열을 의미합니다.
이때 raw.text는 단순히 문자열이므로, 파이썬이 이를 html 소스 코드라고 인식하지 못하는 상황이 발생합니다.
따라서 이를 인식시키기 위해 BeautifulSoup을 이용해 웹사이트의 소스코드를 파싱합니다.

예시 : 네이버TV 1-3위 데이터

그 다음 이전 포스팅에서 다루었던 선택자를 이용해 내가 수집하고자 하는 정보를 직접 수집해봅시다.
만약 인기영상에서 1-3위 영상의 제목, 채널명, 재생수, 좋아요수를 수집하고 싶다면 이들의 선택자를 찾기 전에, 각 영상의 (제목, 채널명, 재생수, 좋아요수)를 담고 있는 컨테이너를 찾아야합니다.
컨테이너는 div.inner 네요.
그리고 제목, 채널명, 재생수, 좋아요수 각각의 선택자는
제목 : dt.title
채널명 : dd.chn
재생수 : span.hit
좋아요수 : span.like 입니다.

이를 이용해 다음과 같은 코드로 정보를 수집합니다.

import requests
from bs4 import BeautifulSoup

raw = requests.get("https://tv.naver.com/r")
html = BeautifulSoup(raw.text, "html.parser")

############################# 이후 과정 ################################

# 1. 컨테이너 선택 : select 함수
container = html.select("div.inner")
'''
container[0] : 1위 영상의 컨테이너
container[1] : 2위 영상의 컨테이너
container[2] : 3위 영상의 컨테이너
# 즉 select 함수는 'div.inner'라는 선택자를 갖는 정보를 각 순서대로 리스트 형태로 저장함'''

# 2. 각 컨테이너별 데이터 수집 : select_one 함수
# 반복문을 이용해 각 컨테이너별로 데이터를 수집한다.
for con in container:
    title = con.select_one("dt.title").text.strip()	#제목
    chn = con.select_one("dd.chn").text.strip()	#채널
    hit = con.select_one("span.hit").text.strip() #조회수
    like = con.select_one("span.like").text.strip()	#좋아요수
    
    print(title, "/", chn, "/", hit, "/", like, "/")


select 함수는 동일한 선택자를 갖는 개체를 여러개 수집하여 list 형태로 저장하는 함수이고,
select_one 함수는 동일한 선택자를 갖는 개체 중 index가 0인(1번째인) 개체를 반환하는 함수입니다.
따라서 같은 이름을 가진 컨테이너는 여러개이므로, select 함수를 이용해 list 형태로 저장하고,
for문을 이용해 순서대로 컨테이너를 꺼내면 되겠죠?

이후 꺼낸 컨테이너의 제목, 채널명 ... 등 정보는 딱 하나밖에 없으므로 select_one 함수를 이용해서 각 변수에 할당해주면 됩니다.

그리고 print를 통해 각각의 정보가 출력되는데, 이때 .text 는 코드가 아닌 코드에 담긴 텍스트(Ex. 제목 : "정근우의 태그업을 무효 선언하는 ... ")를 출력하게 하는 method고, .split( )은 출력하는 텍스트 앞뒤 공백을 제거하여 깔끔하게 해주는 method 입니다.

사실 굳이 print로 안하고 list로 저장해도 상관은 없습니다.

# 추출한 데이터를 list에 담기
# append 함수 사용

import requests
from bs4 import BeautifulSoup

raw = requests.get("https://tv.naver.com/r")
html = BeautifulSoup(raw.text, "html.parser")

# 각 데이터를 담을 list 생성
title = []
chn = []
hit = []
like = []

container = html.select("div.inner")
for con in container:
    t = con.select_one("dt.title").text.strip()	#제목
    c = con.select_one("dd.chn").text.strip()	#채널
    h = con.select_one("span.hit").text.strip() #조회수
    l = con.select_one("span.like").text.strip()	#좋아요수
    
    title.append(t)
    chn.append(c)
    hit.append(h)
    like.append(l)
    


오히려 list로 담으면 더욱 보기 깔끔합니다.
참고로 append는 리스트에 데이터를 추가하는 method 입니다.

다음 포스팅에서는 list가 아닌 엑셀 파일 형식에 직접 데이터를 담아서 저장하는 방법에 대해서 다뤄보겠습니다.


감사합니다.
잘 읽으셨다면 게시글 하단에 ♡(좋아요) 눌러주시면 감사하겠습니다 :)
(구독이면 더욱 좋습니다 ^_^)



- 간토끼(DataLabbit)
- University of Seoul
- Economics, Data Science

728x90

+ Recent posts