파이썬(python)에서 Beautifulsoup을 설치하고 웹 크롤링하는 방법입니다. 쉽게 작성했습니다.

in #kr6 years ago (edited)

정보의 바다로 불리는 인터넷상에 있는 정보를 가져와서 사용하는 기술을 웹 크롤링이라고 부릅니다. 인터넷 상에 있는 데이터를 가져올 때 Open API형태로 제공되면 개발자 입장에서 편하게 데이터를 xml, json 포맷 기반으로 가져올 수 있지만 그렇지 않은 경우라면 약간의 코드를 통해 데이터를 가져올 수 있습니다.
파이썬 진영의 유명한 라이브러리중에 BeautifulSoup이라는 라이브러리를 설치해서 사용하면 필요한 데이터들을 수집할 수 있습니다. 아래의 사이트에 접속하면 다운로드 받아서 바로 BeautifulSoup을 설치할 수 있습니다.

http://www.crummy.com/software/BeautifulSoup/

또는 pip를 사용해서 쉽게 설치할 수 있습니다. 도스창을 실행해서 아래의 명령어로 설치합니다. 파이썬이 설치된 폴더 밑에 Scripts폴더로 이동해서 명령을 실행합니다. 파이썬 3.5가 설치되어 있다면 c:\python35\scripts폴더로 이동해서 실행합니다.

pip install setuptools --upgrade 
pip install beautifulsoup4

2018-04-09_9-32-37.png

웹서버에서 문자열을 가지고 오기 전에 간단한 연습을 먼저 해 봅니다. 아래와 같이 작성되어 있는 문서입니다. HTML문서에서 사용하는 태그는 디스플레이를 꾸며주기 위한 기능으로 원래는 사용합니다. 그런데 웹 크롤링에서는 태그와 속성을 사용해서 필요한 텍스트를 콕 집어서 뽑아내는 방법으로 태그를 이용합니다.
일단 HTML문서나 태그가 익숙하지 않다면 눈으로 태그를 한번 살펴봅니다. html태그 안에 head태그가 있고 대부분의 컨텐츠는 body태그 안쪽에 있습니다. 문단을 나누는 용도로 사용하는 것이 p태그입니다. 별도의 내용들로 구분할 때 보통 div, span태그를 사용합니다.

<!DOCTYPE html>
<html>
    <head>
        <title>
            아주 쉬운 HTML문서 샘플입니다.
        </title>
    </head>
    <body>
        <div>
            <p class="inner-text first-item" id="first">
                교육센터
                <a href="http://www.credu.com" id="credu">
                크레듀
                </a>
            </p>
            <p class="inner-text second-item">
                파이썬 사이트
                <a href="https://www.python.org" id="python">
                Python 
                </a>
            </p>
        </div>
        <p class="outer-text first-item" id="second">
            <b>
                데이터 과학은 멋집니다.
            </b>
        </p>
        <p class="outer-text">
            <b>
                지속적인 학습이 필요합니다. 
            </b>
        </p>
    </body>
</html>

이제는 태그를 파이썬으로 읽어들여서 아래와 같이 작업해 봅니다. pip명령으로 설치한 BeautifulSoup을 메모리에 탑재합니다.

# BeautifulSoup을 임포트하기
from bs4 import BeautifulSoup

아래와 같이 코딩하면 저장된 html문서를 읽어서 스프 객체를 만들고 보기 좋게 정리해서 출력을 합니다. 
page = open('c:\\work\\test01.html', 'rt', encoding='utf-8').read()
soup = BeautifulSoup(page, 'html.parser')
print(soup.prettify())

html문서에 있는 한 단계 아래에 포함된 태그들을 찾을 경우 아래와 같이 접근합니다.

print(list(soup.children))

html문서 내부에 있는 p태그만 찾을 경우 아래와 같이 soup객체에서 find_all()메서드를 호출하면 됩니다. find_all()메서드의 경우 끝까지 검색을 해서 결과를 리스트형태로 리턴합니다.

print(soup.find_all('p'))

2018-04-09_13-01-39.png

하나의 p태그만 찾으면 find메서드를 사용합니다. 결과를 보면 첫번째 p태그만 나오는 것을 볼 수 있습니다.

print(soup.find('p'))

2018-04-09_13-07-23.png

특징이 있는 p태그를 찾을 때는 아래와 같이 합니다. p태그 중에 속성으로 class=”outer-text”를 가지고 있는 경우만 검색합니다.

print(soup.find_all('p', class_='outer-text'))

2018-04-09_13-08-16.png

또는 태그를 명시하지 않고 다만 속성중에 class가 outer-text인 것을 검색합니다.

print(soup.find_all(class_='outer-text'))

또는 태그의 속성중에 id가 first인 것을 검색합니다.

print(soup.find_all(id='first'))

이번에는 html문서에서 head태그를 검색하고, 그 다음을 리턴하고, 다시 그 다음을 리턴하는 코드입니다. body태그 전부가 리턴됩니다.

print(soup.head)
#그 다음을 리턴하기 (\n)
print(soup.head.next_sibling) 
#그 다음을 리턴하기 (body태그)
print(soup.head.next_sibling.next_sibling)

body태그에 대한 참조를 먼저 리턴받고 body다음에 있는 p 태그의 다음 그리고 다음을 리턴받아서 출력해 봅니다. 결과를 확인해 보면 두번째 p태그를 검색한 것을 확인할 수 있습니다.

body = soup.head.next_sibling.next_sibling
print(body.p.next_sibling.next_sibling)

이번에는 태그 안쪽에 있는 문자열만 추출해 봅니다. get_text()메서드를 사용하면 태그 안에 있는 텍스트만 가지고 올 수 있습니다. 우리가 원하는 것은 사실 태그가 아닌 태그 안에 있는 문자열입니다. 대부분 text속성을 사용하거나 get_text()메서드를 호출하면 됩니다.

for tag in soup.find_all('p'):
     print(tag.get_text())

2018-04-09_13-32-12.png

이번에는 html문서에서 a태그만 찾아서 가지고 옵니다.

links = soup.find_all('a')
print(links)

기본적인 연습을 했습니다. 이제 본격적으로 웹페이지에 있는 문자열을 뽑아보는 연습을 한번 해 봅니다. 네이버 웹툰 중에 조석의 마음의 소리 페이지에 접속해봅니다. 주소는 아래와 같습니다.
http://comic.naver.com/webtoon/list.nhn?titleId=20853&weekday=fri

2018-04-09_13-40-46.png

내용을 살펴보면 히트맨이라는 제목이 보입니다. 혹시 웹툰이 업데이트 되어 있으면 눈에 보이는 문자열을 검색해 보시면 됩니다.

2018-04-09_13-42-35.png

인터넷 익스플로러나 크롬 같은 웹브라우져에는 마우스 오른쪽 버튼을 클릭하면 “소스 보기”라는 메뉴가 있습니다. 캡쳐한 화면을 보면 하단에 html문서의 소스가 그대로 나온 것을 볼 수 있습니다. “히트맨”이라는 문자열을 감싸고 있는 앞쪽에 td class=”title” 태그와 속성이 있고 내부에a href=”…” 1131. 히트맨 a태그 닫고 td태그 닫는 것이 보입니다. 우리가 원하는 웹툰의 제목을 가져오려면 td태그 중에 class=”title”이라는 속성이 있는 태그만 검색해 오면 됩니다.
웹서버에 요청하기 위해서 urllib모듈을 임포트 받고, 데이터를 가져오기 위해 BeautifulSoup을 임포트 받습니다.

import urllib.request
from bs4 import BeautifulSoup

네이버의 웹툰중에 하나를 아래의 주소를 통해 로딩합니다. 강사가 제공하는 파일에서 URL주소만 복사해도 됩니다. 검색하기에 용이한 soup객체를 생성합니다.

data =
urllib.request.urlopen('http://comic.naver.com/webtoon/list.nhn?titleId=20853&weekday=fri')
soup = BeautifulSoup(data, 'html.parser')

soup객체를 확인하면 전체 웹 페이지의 모든 내용이 로딩된 것을 확인할 수 있습니다.

print(soup.prettify())

데이터를 가져오고 싶은 웹페이지의 태그의 특징을 미리 알고 있어야 합니다. 네이버 웹툰 페이지에는 테이블 태그의 td태그 중에 td class=’title’와 같이 클래스 속성에 ‘title’로 되어 있는 태그로 감싼 부분의 웹툰의 제목을 포함하는 태그입니다. 아래와 같이 soup객체에서 검색해서 필요한 태그 리스트만 받아옵니다.

cartoons = soup.find_add('td', class_='title')

한건만 받아온다면 아래와 같이 작업해서 결과를 확인해 봅니다.

title = cartoons[0].find('a').text
link = cartoons[0].find('a')['href']
print(title)
print(link)

2018-04-09_14-10-13.png

전체 목록을 받을 경우에는 아래와 같이 실행합니다.

for item in cartoons:   
title = item.find('a').text
print(title)

2018-04-09_14-17-36.png

Sort:  

파이선 쉽게 잘 읽었습니다. 종종 연재해 주시면 많은 도움이 될 것 같군요. 감사합니다.

예! 고맙습니다. 조금씩 정리해서 올리겠습니다.

Coin Marketplace

STEEM 0.20
TRX 0.15
JST 0.029
BTC 63362.14
ETH 2592.64
USDT 1.00
SBD 2.80