위키피디아 한국어 페이지에서 "평화의 소녀상"을 검색하면 다음과 같은 화면이 나타난다. 해당 URL을 requests 모듈을 이용하여 접속하고, html 소스를 가져온다. 

 

위키피디아 검색 결과 페이지

 

BeautifulSoup 클래스의 find( ) 메소드에 HTML 요소의 태그 이름(‘img’)을 전달하면, 해당 태그 부분을 찾아서 객체로 return 해준다. find( ) 명령은 HTML 문서에서 가장 처음으로 만나는 태그를 한 개 찾는다. 앞의 위키피디아 화면에서 가장 먼저 나오는 사진(img 태그)은 "주한 일본 대사관 앞 평화비"라는 설명이 붙어 있는 사진이다. 

 

"평화의 소녀상, 속초"라는 설명이 있는 사진을 나타내는 ‘img’ 태그를 선택하려면, attrs 매개변수에 해당 태그에만 해당하는 고유의 속성을 추가해야 한다. 개발자 도구를 이용하여 해당 태그를 확인할 수 있는데, alt 속성 값으로 이미지 소스 URL 값을 갖는다. 이 속성을 find( ) 메소드의 attrs 매개변수에 입력하는 방식으로, 특정 태그를 선택할 수 있다. 

 

import requests
from bs4 import BeautifulSoup

url = "https://ko.wikipedia.org/wiki/%ED%8F%89%ED%99%94%EC%9D%98_%EC%86%8C%EB%85%80%EC%83%81"
resp = requests.get(url)
html_src = resp.text

soup = BeautifulSoup(html_src, 'html.parser')
                    
photo_first = soup.find(name='img')
print(photo_first)
print("\n")

photo_sockcho = soup.find(name='img', attrs={'src':'//upload.wikimedia.org/wikipedia/commons/thumb/1/16/%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg/220px-%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg'})
print(photo_sockcho)

 

 

실행 결과는 다음과 같다. 두 개의 img 태그를 찾아서 내용을 확인할 수 있다. 이처럼, find( ) 메소드는 특정한 태그를 하나만 찾는 경우에 사용되고, 메모리 관리 측면이나 실행 시간에서 유리하다는 장점을 갖는다. 

 

<img alt="" class="thumbimage" data-file-height="3000" data-file-width="4000" decoding="async" height="173" src="//upload.wikimedia.org/wikipedia/commons/thumb/3/36/Japanese_Embassy_in_Seoul_and_watched_from_behind_a_bronze_statue_of_comfort_women.JPG/230px-Japanese_Embassy_in_Seoul_and_watched_from_behind_a_bronze_statue_of_comfort_women.JPG" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/3/36/Japanese_Embassy_in_Seoul_and_watched_from_behind_a_bronze_statue_of_comfort_women.JPG/345px-Japanese_Embassy_in_Seoul_and_watched_from_behind_a_bronze_statue_of_comfort_women.JPG 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/3/36/Japanese_Embassy_in_Seoul_and_watched_from_behind_a_bronze_statue_of_comfort_women.JPG/460px-Japanese_Embassy_in_Seoul_and_watched_from_behind_a_bronze_statue_of_comfort_women.JPG 2x" width="230"/>

 

 

<img alt="" class="thumbimage" data-file-height="2268" data-file-width="4032" decoding="async" height="124" src="//upload.wikimedia.org/wikipedia/commons/thumb/1/16/%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg/220px-%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/1/16/%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg/330px-%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/1/16/%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg/440px-%ED%8F%89%ED%99%94%EC%9D%98%EC%86%8C%EB%85%80%EC%83%81%28Statute_of_Peace%29.jpg 2x" width="220"/>

 

앞서, requests 모듈을 사용하여 웹 페이지를 요청하고, 응답 객체의 text 속성을 통해 HTML 소스코드를 얻는 과정을 살펴보았다.

 

2019/08/01 - [웹 스크래핑 (Web Scraping)] - [5] 파이썬 웹 스크래핑 - requests 모듈, HTML 소스코드 확인

 

 

HTML 태그와 같이 요소별로 구분하여 HTML 문서를 해석하는 작업을 파싱이라고 부른다. HMTL 소스코드를 파싱(parsing)하고 원하는 정보를 추출하기 위해 BeautifulSoup 라이브러리를 사용한다. 파이썬 클래스로 정의되어 있고, 윈도 명령 프롬프트 또는 터미널 창에서 “pip install beautifulsoup4”를 입력하여 설치한다. 

 

BeautifulSoup 클래스는 매개변수로 전달받은 HTML 소스코드를 해석하여 BeautifulSoup 객체를 생성한다. 이 때, HTML을 파싱(해석)하는 적절한 구문 해석기(파서, parser)를 함께 입력해야 한다. 파서에는 "html.parser", "lxml" 등이 자주 사용된다. (주: XML 구문 해석을 위해서는 "xml" 파서를 따로 설치해서 사용한다.)

 

1) requests 모듈로 html 소스코드 얻기

import requests
from bs4 import BeautifulSoup

url = "https://en.wikipedia.org/wiki/Main_Page"
resp = requests.get(url)
print(resp)
print("\n")

html = resp.text
print(html[:300])
print("\n")

 

requests 모듈의 get( ) 함수의 요청에 웹 서버가 정상 응답하는 경우 코드 200의 값을 갖는다. 응답 객체의 text 속성을 html 변수에 저장하고 일부를 출력하면 html 소스코드를 확인할 수 있다. 

 

<Response [200]>

 

 

<!DOCTYPE html>

<html class="client-nojs" lang="en" dir="ltr">

<head>

<meta charset="UTF-8"/>

<title>Wikipedia, the free encyclopedia</title>

<script>document.documentElement.className=document.documentElement.className.replace(/(^|\s)client-nojs(\s|$)/,"$1client-js$2");RLCONF={"wgCanonicalNamespace

 

 

 

2) html 소스코드를 BeautifulSoup 클래스 객체로 변환하기

soup = BeautifulSoup(html, 'html.parser')
print(type(soup))
print("\n")                 
print(soup.head)
print("\n")
print(soup.body)
print("\n")

 

다음에는 html 문자열을 BeautifulSoup 클래스 객체로 변환한다. type( ) 함수로 soup 객체를 확인하면, BeautifulSoup 클래스 객체라는 것을 알 수 있다. 여기서 soup 객체의 head 부분을 따로 지정할 수 있는데, 다음 실행결과와 같이 <head> 태그 부분이 출력된다. 마찬가지로 <body> 태그 부분을 따로 선택할 수도 있다. 

 

<class 'bs4.BeautifulSoup'>

 

 

<head>

<meta charset="utf-8"/>

<title>Wikipedia, the free encyclopedia</title>

<script>document.documentElement.className=document.documentElement.className.replace(/(^|\s)client-nojs(\s|$)/,"$1client-js$2");RLCONF={"wgCanonicalNamespace":"","wgC ... <중략>...

 

 

<body class="mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Main_Page rootpage-Main_Page skin-vector action-view">

<div class="noprint" id="mw-page-base"></div>

<div class="noprint" id="mw-head-base"></div>

<div class="mw-body" id="content" role="main">

<a id="top"></a>

<div class="mw-body-content" id="siteNotice"><!-- CentralNotice --></div>

<div class="mw-indicators mw-body-content">

</div>  

<h1 class="firstHeading" id="firstHeading" lang="en">Main Page</h1>

<div class="mw-body-content" id="bodyContent">

<div class="noprint" id="siteSub">From Wikipedia, the free encyclopedia</div>

<div id="contentSub"></div>

<div id="jump-to-nav"></div>  ... <이하 생략>...

 

3) BeautifulSoup 클래스 속성 확인하기

print(soup.title)
print(soup.title.name)
print(soup.title.string)

 

<title> 태그를 먼저 선택해서 출력하면 태그의 문자열까지 전부 확인할 수 있다. 여기서 하위 속성인 name을 이용하면, 태그명을 선택할 수 있고, string 속성을 이용하면 문자열을 따로 추출할 수도 있다.

 

<title>Wikipedia, the free encyclopedia</title>

title

Wikipedia, the free encyclopedia

웹사이트에서 정보를 가져올 때, 기본적인 윤리규정과 저작권 등 법률적 이슈에 대하여 유의하여야 한다. 

 

위키피디아(https://ko.wikipedia.org/wiki/)는 로봇 배제 표준에 대하여 웹 사이트에 로봇이 접근하는 것을 방지하기 위한 규약으로, 일반적으로 접근 제한에 대한 설명을 robots.txt에 기술한다.” 라고 말한다. 무분별한 서버 접속은 서버의 안정성을 해치기도 하고, 대부분의 웹 사이트들은 로봇배제표준을 제정하여 게시하고 있다. 

 

 

권고안이기는 하지만 웹 페이지에 접근하기 전에 반드시 로봇 배제 표준을 확인하고 가이드라인을 준수할 필요가 있다.또한, 사이트에 반복적으로 접속하는 행위는 사이트를 공격하는 행위로 받아들여질 수 있기 때문에 서버에 부담을 주지 않는 선에서 제한하는 것이 필요하다. 

 

마지막으로취득한 데이터를 임의로 배포하거나 변경하는 등의 행위는 저작권을 침해할 가능성이 있기 때문에, 로봇배제표준 이외에 저작권 규정을 준수해야 한다. 

 

로봇배제표준을 확인하는 가장 간단한 방법은 웹브라우저 주소창에 "홈페이지 메인 주소/robots.txt"라고 입력하는 것이다.

 

네이버(www.naver.com)의 경우는 다음과 같다. 네이버는 기본적으로 스크래핑(크롤링) 봇의 접근을 금지하고 있다. 

다만, 루트 디렉터리(www.naver.com/)에 대해서는 허용하고 있는 것으로 볼 수 있다. $ 표시는 웹 주소의 마지막을 뜻하기 때문에, 루트 디렉터리의 경우 Allow하고 있다고 해석할 수 있다. 

 

로봇배제표준

로봇배제표준에 대한 상세 설명은 다음 위키피디아 링크를 참조하기 바란다. 

https://ko.wikipedia.org/wiki/%EB%A1%9C%EB%B4%87_%EB%B0%B0%EC%A0%9C_%ED%91%9C%EC%A4%80

 

파이썬 requests 모듈은 웹 서버에 요청을 보내고 응답 객체를 받는데 사용한다. 응답 객체 중에서 HTML 소스 코드를 얻는 방법을 알아본다. 

 

import requests

url = "https://www.wikipedia.org/"
resp = requests.get(url)

html = resp.text
print(html[:1000])

1. requests 모듈을 불러온다.

 

2. 위키피디아 웹 주소를 변수에 저장한다. 

 

3. 웹 서버에 GET 요청을 보내고, 서버가 응답한 객체를 변수에 저장한다.

 

4. text 속성에 HTML 소스코드가 들어 있다. 

 

5. 문자열로 저장되어 있는 HTML 소스코드를 출력한다. 앞에서 1000개의 글자를 지정하여 일부 소스코드만 확인한다. 


<실행 결과 > HTML 소스코드 확인

<!DOCTYPE html>
<html lang="mul" class="no-js">
<head>
<meta charset="utf-8">
<title>Wikipedia</title>
<meta name="description" content="Wikipedia is a free online encyclopedia, created and edited by volunteers around the world and hosted by the Wikimedia Foundation.">
<![if gt IE 7]>
<script>
document.documentElement.className = document.documentElement.className.replace( /(^|\s)no-js(\s|$)/, "$1js-enabled$2" );
</script>
<![endif]>
<!--[if lt IE 7]><meta http-equiv="imagetoolbar" content="no"><![endif]-->
<meta name="viewport" content="initial-scale=1,user-scalable=yes">
<link rel="apple-touch-icon" href="/static/apple-touch/wikipedia.png">
<link rel="shortcut icon" href="/static/favicon/wikipedia.ico">
<link rel="license" href="//creativecommons.org/licenses/by-sa/3.0/">
<style>
.sprite{background-image:url(portal/wikipedia.org/assets/img/sprite-3f2e1b8f.png);background-image:linear-gradient(transparent,transparent),url(portal/wikipedia.org/assets/img/sprite-3f2e1b8f.svg);background

 

 

초보의, 초보에 의한, 초보를 위한 파이썬 코딩!

 

복잡한 코딩은 피하겠습니다. 간단하게 따라하면서 바로 업무에 적용할 수 있는 알고리즘을 찾아서 소개하겠습니다. 포기하지 마시고 직접 따라하시다보면 파이썬 언어도 자연스럽게 이해가 될 수 있도록 말이죠.

 

 

 

오늘은 상장기업 재무제표(제무정보) 수집 업무 자동화를 해보겠습니다.

 

 

Step 1: 데이터를 수집할 소스를 정한다.

 

이번 예제에서는 KISLINE(http://media.kisline.com/highlight/mainHighlight.nice?nav=1&paper_stock=005930) 사이트에서 삼성전자(005930)의 재무정보를 가져와 보겠습니다. url 마지막 부분에 "paper_stock=005930"에서 숫자 6자리가 주식종목코드입니다. 이 부분을 바꿔주면 원하는 상장회사의 재무정보가 있는 KISLINE 웹페이지를 호출할 수 있습니다.

 

 

Step 2: 데이터 수집을 위한 코드를 작성한다.

 

코드는 아주 간단하죠?^^ pandas 라이브러리와 dataframe을 설명하고 이해하려면 상당히 많은 시간이 필요하지만, 직장인들이 업무에 적용할 때는 엑셀의 내장함수를 사용하 듯 그냥 따라하는 것도 괜찮다고 생각합니다. 일단 업무에 적용하고, 세세한 작동원리와 이론에 대해서는 차근차근 보충해 나가는 방법을 권장합니다. 이런 게 실사구시의 정신 아닐까요? ^^

 

import pandas as pd

 

#html 객체의 표(table)를 pandas dataframe으로 가져온다
url = 'http://media.kisline.com/highlight/mainHighlight.nice?nav=1&paper_stock=005930'
tables = pd.read_html(url)

 

#엑셀로 저장하기
df = tables[4]    #개별IFRS 연간 재무제표
df.to_excel('output.xlsx')

 

 

 

Step 3: 데이터를 원하는 형태로 정리한다. 

 

저장된 엑셀 파일을 열어서 확인해 보면, 불필요한 셀들이 있는데요. 이런 부분을 제거해서 필요한 부분만 남기는 것을 데이터 클린징이라고 부릅니다. 이 부분도 자동화할 수 있지만, 난이도가 꽤 있는 작업이라서 오늘은 다루지 않겠습니다.

 

저는 아래와 같이 불필요한 셀을 삭제해서 정리하였습니다. 각자 필요한 양식으로 만들어서 사용하시면 되겠습니다.

 

 

 

 

 

 

+ Recent posts