7. 크롤링을 위한 웹 기본지식#
이번 장에서는 크롤링을 하기 위해 사전에 알고 있으면 도움이 되는 인코딩, 웹의 동작 방식, HTML과 CSS에 대해 알아보겠다.
7.1. 인코딩에 대한 이해#
7.1.1. 인간과 컴퓨터 간 번역의 시작, ASCII#
한글이 포함된 엑셀이나 CSV 파일을 불러올 때, 혹은 한글로 된 데이터를 크롤링하면 오류가 뜨거나 읽을 수 없는 문자로 나타나는 경우가 종종 있다. 이는 한글 인코딩 때문에 발생하는 문제이며, 이러한 현상을 흔히 ‘인코딩이 깨졌다’라고 표현한다. 인코딩이란 사람이 사용하는 언어를 컴퓨터가 사용하는 0과 1로 변환하는 과정을 말하며, 이와 반대의 과정을 디코딩이라고 한다.
이렇듯 사람과 컴퓨터 간의 언어를 번역하기 위해 최초로 사용된 방식이 아스키(ASCII: American Standard Code for Information Interchange)다. 0부터 127까지 총 128개 바이트에 알파벳과 숫자, 자주 사용되는 특수문자 값을 부여하고, 문자가 입력되면 이에 대응되는 바이트가 저장된다. 그러나 아스키의 ‘American’이라는 이름에서 알 수 있듯이 이는 영어의 알파벳이 아닌 다른 문자를 표현하는 데 한계가 있으며, 이를 보완하기 위한 여러 방법이 나오게 되었다.

Fig. 7.1 아스키 코드 표#
7.1.2. 한글 인코딩 방식의 종류#
인코딩에 대한 전문적인 내용은 이 책의 범위를 넘어가며, 크롤링을 위해서는 한글을 인코딩하는 데 쓰이는 EUC-KR과 CP949, UTF-8 정도만 이해해도 충분하다. 만일 ‘퀀트’이라는 단어를 인코딩한다면 어떤 방법이 있을까요? 먼저 ‘퀀’과 ‘트’라는 문자 자체에 해당하는 코드를 부여해 나타내는 방법이 있다. 아니면 이를 구성하는 모음과 자음을 나누어 ‘ㅋ’,’ㅜ’,’ㅓ’,’ㄴ’,’ㅌ’,’ㅡ’ 각각에 해당하는 코드를 부여하고 이를 조합할 수도 있다. 전자와 같이 완성된 문자 자체로 나타내는 방법을 완성형, 후자와 같이 각 자모로 나타내는 방법을 조합형이라고 한다.
한글 인코딩 중 완성형으로 가장 대표적인 방법은 EUC-KR 이다. EUC-KR은 현대 한글에서 많이 쓰이는 문자 2,350개에 번호를 붙인 방법이다. 그러나 2,350개 문자로 모든 한글 자모의 조합을 표현하기 부족해, 이를 보완하고자 마이크로소프트가 도입한 방법이 CP949 이다. CP949는 11,720개 한글 문자에 번호를 붙인 방법으로 기존 EUC-KR보다 나타낼 수 있는 한글의 개수가 훨씬 많아졌다. 윈도우의 경우 기본 인코딩이 CP949로 되어있다.
조합형의 대표적 방법인 UTF-8은 모음과 자음 각각에 코드를 부여한 후 조합해 한글을 나타낸다. 조합형은 한글뿐만 아니라 다양한 언어에 적용할 수 있다는 장점이 있어 전 세계 웹페이지의 대부분이 UTF-8로 만들어지고 있다.

Fig. 7.2 웹페이지에서 사용되는 인코딩 비율#
7.2. 웹의 동작 방식#
크롤링은 웹사이트의 정보를 수집하는 과정이다. 따라서 웹이 어떻게 동작하는지 이해할 필요가 있다.
먼저 클라이언트란 여러분의 데스크톱이나 휴대폰과 같은 장치와 크롬이나 파이어폭스와 같은 소프트웨어를 의미한다. 서버는 웹사이트와 앱을 저장하는 컴퓨터를 의미한다. 클라이언트가 특정 정보를 요구하는 과정을 ‘요청’이라고 하며, 서버가 해당 정보를 제공하는 과정을 ‘응답’이라고 한다. 그러나 클라이언트와 서버가 연결되어 있지 않다면 둘 사이에 정보를 주고받을 수 없으며, 이를 연결하는 공간이 바로 인터넷이다. 또한 건물에도 고유의 주소가 있는 것처럼, 각 서버에도 고유의 주소가 있는데 이것이 인터넷 주소 혹은 URL이다.
여러분이 네이버에서 경제 기사를 클릭하는 경우를 생각해보자. 클라이언트는 사용자인 여러분이고, 서버는 네이버이며, URL은 www.naver.com 이 된다. 경제 기사를 클릭하는 과정이 요청이며, 클릭 후 해당 페이지를 보여주는 과정이 응답이다.

Fig. 7.3 웹 환경 구조#
7.2.1. HTTP#
클라이언트가 각기 다른 방법으로 데이터를 요청한다면, 서버는 해당 요청을 알아듣지 못할 것이다. 이를 방지하기 위해 규정된 약속이나 표준에 맞추어 데이터를 요청해야 한다. 이러한 약속을 HTTP(HyperText Transfer Protocol)라고 한다.
클라이언트가 서버에게 요청의 목적이나 종류를 알리는 방법을 HTTP 요청 방식(HTTP Request Method)이라고 한다. HTTP 요청 방식은 크게 Table 7.1와 같이 GET, POST, PUT, DELETE라는 네 가지로 나눌 수 있지만 크롤링에는 GET과 POST 방식이 대부분 사용되므로 이 두 가지만 알아도 충분하다. GET 방식과 POST 방식의 차이 및 크롤링 방법은 나중에 다시 자세하게 다룬다.
요청방식 |
내용 |
---|---|
GET |
특정 정보 조회 |
POST |
새로운 정보 등록 |
PUT |
기존 특정 정보 갱신 |
DELETE |
기존 특정 정보 삭제 |
인터넷을 사용하다 보면 한 번쯤 ‘이 페이지를 볼 수 있는 권한이 없음(HTTP 오류 403 - 사용할 수 없음)’ 혹은 ‘페이지를 찾을 수 없음(HTTP 오류 404 - 파일을 찾을 수 없음)’이라는 오류를 본 적이 있을 것이다. 여기서 403과 404라는 숫자는 클라이언트의 요청에 대한 서버의 응답 상태를 나타내는 HTTP 상태 코드이다.
HTTP 상태 코드는 100번대부터 500번대까지 있으며, 성공적으로 응답을 받을 시 200번 코드를 받는다. 각 코드에 대한 내용은 HTTP 상태 코드를 검색하면 확인할 수 있으며, 크롤링 과정에서 오류가 발생할 시 해당 코드를 통해 어떤 부분에서 오류가 발생했는지 확인이 가능하다.
코드 |
상태 |
내용 |
---|---|---|
1xx |
Informational (조건부 응답) |
리퀘스트를 받고, 처리 중에 있음 |
2xx |
Success (성공) |
리퀘스트를 정상적으로 처리함 |
3xx |
Redirection (리디렉션) |
리퀘스트 완료를 위해 추가 동작이 필요함 |
4xx |
Client Error (클라이언트 오류) |
클라이언트 요청을 처리할 수 없어 오류 발생 |
5xx |
Server Error (서버 오류) |
서버에서 처리를 하지 못하여 오류 발생 |
7.3. HTML과 CSS#
클라이언트와 서버가 데이터를 주고받을 때는 디자인이라는 개념이 필요하지 않다. 그러나 응답받은 정보를 사람이 확인하려면 보기 편한 방식으로 바꾸어줄 필요가 있는데 웹페이지가 그러한 역할을 한다. 웹페이지의 제목, 단락, 목록 등 레이아웃을 잡아주는 데 쓰이는 대표적인 마크업 언어가 HTML(HyperText Markup Language)이다. HTML을 통해 잡혀진 뼈대에 글자의 색상이나 폰트, 배경색, 배치 등 화면을 꾸며주는 역할을 하는 것이 CSS(Cascading Style Sheets)다.
우리의 목적은 웹페이지를 만드는 것이 아니므로 HTML과 CSS에 대해 자세히 알 필요는 없다. 그러나 크롤링하고자 하는 데이터가 웹페이지의 어떤 태그 내에 위치하고 있는지, 어떻게 크롤링하면 될지 파악하기 위해서는 HTML과 CSS에 대한 기본적인 지식은 알아야 한다.
HTML과 CSS의 실습은 아래 페이지에서 해볼 수 있다.
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_intro
7.3.1. HTML 기본 구조#
HTML은 크게 메타 데이터를 나타내는 head와 본문을 나타내는 body로 나누어진다. head에서 title은 웹페이지에서 나타나는 제목을 나타내며 body 내에는 본문에 들어갈 각종 내용들이 포함되어 있다. w3schools 사이트에서 아래 소스코드를 복사해 좌측에 붙여넣은 후, 상단의 [Run] 버튼을 클릭해보자.
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h2> This is page heading </h2>
<p> This is first paragraph text </p>
</body>
</html>

Fig. 7.4 HTML 기본 구조#
<head> 부분에 입력한 내역은 실습 페이지 구조 상 확인되지 않지만, <body> 부분에 입력한 글자들은 우측 결과물 페이지에서 확인이 가능하다. <h2>와 <p> 등의 태그가 하는 역할들에 대해서 더욱 자세히 알아보도록 하겠다.
7.3.2. 태그와 속성#
HTML 코드는 태그와 속성, 내용으로 이루어져 있다. 크롤링한 데이터에서 특정 태그의 데이터만을 찾는 방법, 특정 속성의 데이터만을 찾는 방법, 뽑은 자료에서 내용만을 찾는 방법 등 원하는 값을 찾는 방법이 모두 다르기 때문에 태그와 속성에 대해 좀 더 자세히 살펴보겠다.

Fig. 7.5 HTML 구성 요소 분석#
꺾쇠(<>)로 감싸져 있는 부분을 태그라고 하며, 여는 태그 <>가 있으면 반드시 이를 닫는 태그인 </>가 쌍으로 있어야 한다. 속성은 해당 태그에 대한 추가적인 정보를 제공해주는 것으로, 뒤에 속성값이 따라와야 한다. 내용은 우리가 눈으로 보는 텍스트 부분을 의미한다. Fig. 7.5의 HTML 코드는 문단을 나타내는 <p> 태그, 정렬을 나타내는 align 속성과 center 속성값을 통해 가운데 정렬을 지정하며, 내용에는 ‘퀀트 투자’를 나타내고, </p> 태그를 통해 태그를 마쳤다.
7.3.3. h 태그와 p 태그#
h 태그는 폰트의 크기를 나타내는 태그이며, p 태그는 문단을 나타내는 태그다. 이를 사용한 간단한 예제는 다음과 같다.
<html>
<body>
<h1>Page heading: size 1</h1>
<h2>Page heading: size 2</h2>
<h3>Page heading: size 3</h3>
<p>Quant Portfolio</p>
<p>By Henry</p>
</body>
</html>

Fig. 7.6 h 태그와 p 태그 예제#
h 태그의 숫자가 작을수록 텍스트 크기는 커지며, 숫자는 1에서 6까지 지원된다. 또한 p 태그를 사용하면 각각의 문단이 만들어진다.
7.3.4. 리스트를 나타내는 ul 태그와 ol 태그#
ul과 ol 태그는 리스트(글머리 기호)를 만들 때 사용됩니다. ul은 순서가 없는 리스트(unordered list), ol은 순서가 있는 리스트(ordered list)를 만든다.
<html>
<body>
<h2> Unordered List</h2>
<ul>
<li>List 1</li>
<li>List 2</li>
<li>List 3</li>
</ul>
<h2> Ordered List</h2>
<ol>
<li>List A</li>
<li>List B</li>
<li>List C</li>
<li>List D</li>
</ol>
</body>
</html>

Fig. 7.7 리스트 관련 태그 예제#
ul 태그로 감싼 부분은 글머리 기호가 순서가 없는 •으로 표현되며, ol 태그로 감싼 부분은 숫자가 순서대로 표현된다. 각각의 리스트는 li를 통해 생성된다.
7.3.5. table 태그#
table 태그는 표를 만드는 태그다.
<html>
<body>
<h2>Sample Table</h2>
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
</table>
</body>
</html>

Fig. 7.8 리스트 관련 태그 예제#
table 태그 내의 tr 태그는 각 행을 의미하며, 각 셀의 구분은 th 혹은 td 태그를 통해 구분할 수 있다. th 태그는 진하게 표현되므로 주로 테이블의 제목에 사용되고, td 태그는 테이블의 내용에 사용된다.
7.3.6. a 태그와 img 태그 및 속성#
a 태그와 img 태그는 다른 태그와는 다르게, 혼자 쓰이기보다는 속성과 결합해 사용된다. a 태그는 href 속성과 결합해 다른 페이지의 링크를 걸 수 있다. img 태그는 src 속성과 결합해 이미지를 불러온다.
<html>
<body>
<h2>a tag & href attribute</h2>
<p>HTML links are defined with the a tag.
The link address is specified in the href attribute:</p>
<a href="https://blog.naver.com/leebisu">Henry's Quantopia</a>
<h2>img tag & src attribute</h2>
<p>HTML images are defined with the img tag,
and the filename of the image source is
specified in the src attribute:</p>
<img src="https://www.python.org/static/img/python-logo.png",
width="200",height="100">
</body>
</html>

Fig. 7.9 a 태그와 src 태그 예제#
a 태그 뒤 href 속성에 연결하려는 웹페이지 주소를 속성값(https://blog.naver.com/leebisu)으로 입력한 후 내용(Henry’s Quantopia)을 입력하면, 내용 텍스트에 웹페이지의 링크가 추가된다. img 태그 뒤 src 속성의 속성값에는 불러오려는 이미지 주소를 입력하며, width 속성과 height 속성을 통해 이미지의 가로 세로 길이를 조절할 수도 있다. 페이지 내에서 링크된 주소를 모두 찾거나, 모든 이미지를 저장하려고 할 때 속성값을 찾으면 손쉽게 원하는 작업을 할 수 있다.
7.3.7. div 태그#
div 태그는 화면의 전체적인 틀(레이아웃)을 만들 때 주로 사용하는 태그다. 단독으로도 사용될 수 있으며, 꾸밈을 담당하는 style 속성과 결합되어 사용되기도 한다.
<html>
<body>
<div style="background-color:black;color:white">
<h5>First Div</h5>
<p>Black backgrond, White Color</p>
</div>
<div style="background-color:yellow;color:red">
<h5>Second Div</h5>
<p>Yellow backgrond, Red Color</p>
</div>
<div style="background-color:blue;color:grey">
<h5>Second Div</h5>
<p>Blue backgrond, Grey Color</p>
</div>
</body>
</html>

Fig. 7.10 div 태그 예제#
div 태그를 통해 총 세 개의 레이아웃으로 나누어진 것을 알 수 있다. style 속성 중 background-color는 배경 색상을, color는 글자 색상을 의미하며, 각 레이아웃마다 다른 스타일이 적용되었다.
7.3.8. CSS#
CSS는 앞서 설명했듯이 웹페이지를 꾸며주는 역할을 한다. head에서 각 태그에 CSS 효과를 입력하면 본문의 모든 해당 태그에 CSS 효과가 적용된다. 이처럼 웹페이지를 꾸미기 위해 특정 요소에 접근하는 것을 셀렉터(Selector)라고 한다.
<html>
<head>
<style>
body {background-color: powderblue;}
h4 {color: blue;}
</style>
</head>
<body>
<h4>This is a heading</h4>
<p>This is a first paragraph.</p>
<p>This is a second paragraph.</p>
</body>
</html>

Fig. 7.11 css 예제#
head의 style 태그에서 여러 CSS 효과가 정의되었다. 먼저 body의 전체 배경 색상을 powderblue로 설정했으며, h4 태그의 글자 색상은 파란색(blue)으로 설정했다. body 태그 내에서 style에 태그를 주지 않더라도, head에서 정의한 CSS 효과가 모두 적용된다.
7.3.9. 클래스와 id#
위의 예제에서 클래스 속성을 이용하면 특정 이름을 가진 클래스에 동일한 효과를 적용할 수 있다.
<html>
<style>
.language {
background-color: tomato;
color: white;
padding: 10px;
}
.desc {
background-color: moccasin;
color: black;
padding: 10px;
}
</style>
<div>
<h2 class="language">Python</h2>
<p class="desc"> Python is a high-level, general-purpose programming language.</p>
</div>
<div>
<h2>SQL</h2>
<p>SQL is a domain-specific language used in programming and designed for managing data held in a RDBMS, or for stream processing in a RDBMS. </p>
</div>
<div>
<h2 class="language">R</h2>
<p class="desc">R is a free software environment for statistical computing and graphics.</p>
<div>
</html>

Fig. 7.12 class 예제#
셀렉터를 클래스에 적용할 때는 클래스명 앞에 마침표(.)를 붙여 표현한다. 위 예제에서 language 클래스는 배경 색상이 tomato, 글자 색상은 흰색, 여백은 10px로 정의되다. desc 클래스는 배경 색상이 moccasin, 글자 색상은 검은색, 여백은 10px로 정의되었다. 본문의 첫 번째(Python)와 세 번째(R) 레이아웃의 h2 태그 뒤에는 language 클래스를, p 태그 뒤에는 desc 클래스를 속성으로 입력했다. 따라서 해당 레이아웃에만 CSS 효과가 적용되며, 클래스 값이 없는 두 번째 레이아웃에는 효과가 적용되지 않는다.
id 또한 이와 비슷한 역할을 한다. HTML 내에서 클래스는 여러 개가 정의될 수 있는 반면, id는 단 하나만 사용하기를 권장한다.
<html>
<head>
<style>
#myHeader {
background-color: lightblue;
color: black;
padding: 15px;
text-align: center;
}
</style>
</head>
<body>
<h1 id="myHeader">My Header</h1>
</body>
</html>

Fig. 7.13 class 예제#
셀렉터를 id에 적용할 때는 id명 앞에 샵(#)를 붙여 표현하며, 페이지에서 한 번만 사용된다는 점을 제외하면 클래스와 사용 방법이 거의 동일하다. 클래스나 id 값을 통해 원하는 내용을 크롤링하는 경우도 많으므로, 각각의 이름 앞에 마침표(.)와 샵(#) 을 붙여야 한다는 점을 꼭 기억해야 한다.
Note
HTML과 관련해 추가적인 정보가 필요하거나 내용이 궁금하다면 아래 웹사이트를 참고하기 바란다.
w3schools: https://www.w3schools.in/html-tutorial/