정적 웹 크롤링 with Python

Jason·2020년 7월 1일
0

웹 크롤링

목록 보기
1/1

웹 크롤링이란?

웹사이트를 분석하여 원하는 데이터를 추출해내는 과정.

크롤링은 보통 2가지 방법을 활용하여 수행할 수 있는데 첫 번째가 정적인 화면을 크롤링 하는 것, 두 번째가 동적인 화면을 크롤링 하는 것이다.

  1. 정적 크롤링: BeautifulSoup을 활용하여 수행
  2. 동적 크롤링: Selenium을 활용하여 수행

이 포스트에서는 먼저 정적인 화면을 크롤링하는 과정을 서술하고자 한다. 이번에 수행할 크롤링 작업은 빌보드 top 100 차트에서 순위, 곡 이름, 그리고 가수 이름까지 3개의 값을 추출하는 것이다.

가상환경 세팅

크롤링을 수행하기 전 먼저 miniconda를 이용하여 가상환경을 구축한다.

conda create -n crawlingProjects python=3.8

파이썬 3.8 버전 및 관련 패키지들이 설치된 crawlingProject라는 가상환경을 생성하고,

conda activate crawlingProjects

해당 가상환경으로 들어간다.

pip install bs4 requests

crawlingProjects 가상환경 내에서 크롤링에 필요한 bs4와 requests 라이브러리들을 설치한다.

이제 크롤링을 수행하기 위한 가상환경이 준비되었다!

requests와 BeautifulSoup을 이용해 추출하고자 하는 정보 가져오기

이제 조성된 가상환경 내에 알맞은 디렉토리를 생성하고, billboardcrawling.py라는 파이썬 파일을 생성해 보자!

mkdir billboard # billboard 디렉토리 생성
cd billboard # billboard 디렉토리로 이동
vi billboardcrawling.py # billboardcrawling.py 파일 생성 및 오픈

billboardcrawling.py에서는 우리가 크롤링을 위해 설치한 requests와 BeautifulSoup를 사용할 수 없기에 이들을 import 해 오자.

import requests
from bs4 import BeautifulSoup
  • requests - HTTP 요청을 담당하는 라이브러리
  • BeautifulSoup (bs4) 내에 속함 - HTML로부터 우리가 원하는 데이터를 추출할 수 있게 해줌

먼저, requests 라이브러리의 get 메쏘드를 사용하면 우리가 데이터를 추출할 url에서 html 정보를 불러올 수 있으며, 이를 req라는 변수에 저장해보자.

req = requests.get("https://www.billboard.com/charts/hot-100") # HTTP - GET REQUEST

그 다음, get request로 받은 html 정보를 req.text를 통해 텍스트(str) 객체로 변환시킨다. .text는 BeautifulSoup에서 제공하는 메쏘드로서, html 형태의 데이터에서 텍스트 부분만을 빼 온다.

html = req.text

그러나, 이 html 객체는 너무 방대한 양의/우리가 원하지 않는 정보까지 전부 다 텍스트로 가지고 있기에, 우리가 원하는 데이터만을 추출하기 위한 사전 작업으로서 BeautifulSoup을 이용하여 Parsing을 해보자.

soup_obj = BeautifulSoup(html, 'html.parser')

BeautifulSoup을 이용해 html 객체를 파이썬 객체로 parsing한다. 두 번째 매개변수는 어떤 parser를 사용할 것인지를 지정하는 역할을 함. 이를 soup라는 객체에 저장.

  • BeautifulSoup Parser의 종류
  1. 'html.parser': 적당히 빠르고 가벼움
  2. 'lxml': 매우 빠르나 외부 C 라이브러리에 의존
  3. 'xml': 매우 빠르고 xml 해석기 지원함 / 외부 C라이브러리에 의존
  4. 'html5lib': 웹 브라우저 방식으로 페이지 해석, HTML5 생성 / 외부 파이썬 라이브러리 사용, 아주 느리고 파이썬 2 버전만 사용

크롤링 및 데이터의 딕셔너리 저장

자 이제 우리가 원하는 데이터를 크롤링할 준비가 완료되었다!

지금부터는 크롬의 개발자 도구를 활용하여 우리가 데이터를 뽑아내고 싶은 요소의 HTML/CSS 구조를 파악하고, 그에 맞춰 코드를 작성하면 된다.

빌보드 차트의 경우, CSS Selector를 이용하여 크롤링을 수행해 보자. CSS Selector를 이용해서 파싱된 텍스트 파일에서 우리가 원하는 데이터를 뽑아내려면 soup.select() 메쏘드를 사용하면 된다.

rank = soup_obj.select("li > button > span > span.chart-element__rank__number")

song = soup_obj.select("li > button > span.chart-element__information > span.chart-element__information__song")

artist = soup_obj.select("li > button > span.chart-element__information > span.chart-element__information__artist")

우리가 뽑아내고 싶은 데이터는 Rank, song, artist 세 가지이므로 soup_obj.select()의 요소로서 각각에 해당하는 CSS 셀렉터를 넣어준다.

이제 rank, song, artist는 100개의 정보를 각각 가지고 있는 리스트 형태의 자료구조가 되어 있다.

그렇다면 세 리스트를 top_chart라는 딕셔너리에 저장해서 한번에 출력해보자.

top_chart = [] # 빈 리스트를 전역변수로 생성
for eachLine in zip(rank, song, artist):
	top_chart.append(
        {
            'rank'   : eachLine[0].text,
            'song'   : eachLine[1].text,
            'artist' : eachLine[2].text,
        }
) 

zip() 함수를 이용해 rank, song, artist라는 세 리스트들 안의 값들 중 0번째 인덱스부터 같은 인덱스를 가진 값 3개씩 묶어 준다 (3개의 값을 가지는 리스트 생성)

그 이후, for 문을 이용해 3개의 값을 가지는 리스트 100개를 생성한다 (인덱스 0부터 99까지). 리스트 하나마다 eachLine이라는 객체에 저장되고, 이 각각의 eachLine을 top_chart 리스트에 딕셔너리 형태로 append한다.

그러므로, top_chart 리스트에는 'rank', 'song', 'artist' 세 가지의 키와 그에 상응하는 값을 가지는 딕셔너리 100개가 차례로 저장된다.

이렇게 리스트에 저장한 딕셔너리들을 하나하나 출력하기 위해서, for문을 사용한다.

for i in top_chart:
	print(i)
profile
Mathematician and Developer

0개의 댓글