시리즈물/데이터 수집을 위한 크롤링

[크롤링] 데이터 수집을 위한 크롤링 2편 : 크롤링에 필요한 필수 요소들

포도알77 2019. 3. 2. 09:00
 데이터 수집을 위한 크롤링 연속 포스팅 

[크롤링] 데이터 수집을 위한 크롤링 1편 : 크롤링이란 무엇인가?

[크롤링] 데이터 수집을 위한 크롤링 2편 : 크롤링에 필요한 필수 요소들

[크롤링] 데이터 수집을 위한 크롤링 3편 : JSON, 더 자세한 설명

[크롤링] 데이터 수집을 위한 크롤링 4편 : Java의 설치와 간단한 Jsoup 예제

[크롤링] 데이터 수집을 위한 크롤링 5편 : Yahoo 파이낸스를 이용한 환율 크롤링

1. 크롤링이란?

전편에 이어서, 이번에는 크롤링에 필요한 필수 요소들을 짚어보도록 하자.  


 

2. 크롤링 대상

 어떠한 목적을 가지고 정보 수집을 하는 경우, 그 목적에 부합하는 대상이 필요하다. 당연하게도 웹 크롤링의 대상은 웹 자원이다. 웹 자원의 경우 웹 문서와 API 결과, 좀 더 나아가서는 웹 서비스를 제공하는 서버의 IP, 정보, 프레임워크등등 다양하다.   


 이 연속 포스팅에서는 쉽고 간단하게 내용을 정리하기 위해서 웹 문서와 API를 크롤링 대상으로 선정할 예정이다.  


 

3. 크롤링에 필요한 사전 지식

 웹 문서와 API를 크롤링 대상으로 선정하였으므로, 웹 문서를 구성하는 언어인 하이퍼텍스트 마크업 랭귀지(HTML)과 API의 결과로 제공되는 포맷 (XML, JSON 등등)을 분석하고 데이터를 추출하는 방법을 알아야 한다.  

 (1) HTML HTML은 긴 역사를 자랑하는 언어이자, 웹 페이지를 형식화하여 사용자가 시각적으로 볼 수 있도록 하는 언어이다. 비유적으로 본다면, 문서의 제목은 30 포인트, 중앙 정렬등 문서가 보이는 형태를 규정하는 언어로 볼 수 있으며, 당연히 이 언어를 이해하는 프로그램(브라우저 등)이 이를 해석하고 동일한 형태로 사용자에게 제공한다.  

 대부분의 이 블로그를 보는 사람의 경우 프로그래밍을 학습한 사람이겠지만, 아닐 수도 있으니 F12를 눌러 개발자 도구를 열어보자.





 위 이미지는 이 블로그의 특정 페이지에서 개발자 도구를 열어 본 것이다. 좌측 상단에서 중간까지 위하고 있는 공간에 알록달록 영어와 숫자 그리고 특수문자들로 이루어진 괴랄한 형태의 문자들이 HTML로 구성되어 있는 소스코드이다. 


 HTML에 대해서 조금 더 알아보는 포스트를 준비하겠지만, 우선 간략하게 짚어보자.

 HTML은 특정 기능을 하는 태그로 구성되어 있다. 이러한 태그는 <태그1>과 같이 부등호와 태그 이름으로 구성되어 있다. 태그이름은 다양한데, 대표적으로 <html></html>, <head></head>, <body></body>를 예로 들 수 있다.

 html은 <html>과 </html>사이에 들어오는 값들이 html이라는 것을 의미한다. 더 다양한 태그들은 아래의 링크에서 알아볼 수 있다.



 https://www.w3schools.com/tags/tag_html.asp


우리가 알고 싶어하는 정보들은 이러한 태그들에 둘러 쌓여있거나, 포함되어 있다.





 위 그림은 네이버에서 사과를 검색했을 때 나오는 HTML로, 좌측에 보이는 "온거로 먹는 청송꿀땡이사과 5kg 1..." 이미지와 링크에 대한 정보들이 우측의 HTML상에서도 똑같이 표현되고 있다.

 즉, 내가 "사과"를 검색했을때 제일 먼저 노출되는 상품의 가격과 홈페이지의 링크, 리뷰 정보를 알고 싶다면, 이 웹 페이지의 "tit single" 클래스를 가지는 div 태그안의 a 태그의 href 정보와, "dsc price"클래스를 가지는 div 태그 내부의 가격 정보 그리고 "dsc compare" 클래스를 가지는 div 태그안의 em 태그의 리뷰 정보를 가져오면 된다.


 만약 설명이 이상해서 이해하지 못했다면 사과한다. 그러려고 사과를 이 포스팅에서 계속해서 사용하는 것이다.



  (2) API API는 Application Programming Interface로 특정 URL에 들어갔을때 데이터가 반환되는 것과 전혀 단어 의미가 맞지 보일 수 있다. 이를 구구절절 이야기 할 수 없으니 구글링을 생활화하자. 아무튼 REST API를 통해서 반환되는 데이터를 크롤링 대상으로 선정하였다면, 위의 HTML처럼 반환되는 형식을 읽을 줄 알아야 한다. 

  반환되는 형식은 현재 기준으로 크게 JSON과 XML 그리고 독자 형식으로 나눌 수 있다. 독자 형식의 경우 그 형식을 분명 설명하는 페이지가 별도로 구성되어 있을것이니 이는 넘어가도록 하고 JSON 형식과 XML 형식을 예로 들어 보자. 

  JSON 형식JavaScript Object Notation으로 XML이 가지는 용량 문제를 해결하기 위해서 사용되는 형식이다. JSON.ORG에서 굉장히 복잡하게 설명하고 있으나 아래와 같이 간단하게 구분할 수 있다.

1. Object, 오브젝트는 데이터를 뭉쳐놓은 것으로 이해할 수 있다. 이러한 데이터를 가져오기 위해서 Key와 Value 쌍으로 표현한다.

    { '블로그명' : 'IT 방랑기', '주소' : ['https://fatc.club', 'http://fatc.club'] }


2. Array, 잘 알려져 있듯 배열이며 Javascript 특성상 동일한 타입이 아니더라도 하나의 배열로 정의할 수 있다.

     [ '1', 2, 3.666 ]


3. string, 문자열을 나타낸다. 원칙상 쌍 따옴표를 쓰지만 홑따옴표로도 표현할 수 있다.

    '문자열'  또는 "문자열"

    'A씨가 "IT방랑기에서 봤다"라고 말했다'와 같이 따옴표를 혼용할 수 있다.


4. number, 숫자들을 나타낸다. 정수와 소수점을 모두 포함한다.

    1, 2.5, -1, 1000000000



 XML 형식eXtensible Markup Language로 기존의 HTML이 가지는 태그의 유한성의 문제를 해결하기 위해서 등장했다고 이해하면 비약이지만 이렇게 이해하자. 
 
 상호간 데이터 교환을 위해서 자신만의 태그를 정의하고 이를 태그들에 기반해서 표현하는 형식이다. XML을 정의하는 문서는 별도로 DTD나 XML 스키마등 다양하다. (XML은 매우 좋은 형식임에 틀림없지만..애석하게도 XML 형식은 너무 길다. 그래서 나는 잘 안쓰므로 JSON만 다룰 것이다.)  

 그렇다면, API으로 반환되는 JSON 데이터의 결과값을 실제로 구경해보자. 링크를 눌러 반환되는 결과 값을 보자. 

  

  http://coinlist.xyz/api/v1/top50  


 반환되는 형식은 Object로 { "success" : true, "data" : [] } 의 형태를 가지고 있다. success는 성공 여부를 true, false로 나태나며, data에는 Object가 배열로 저장되어 있다. data에 포함되어있는 Object는 "name", "code", "type", "supply", "h24Volue", "change", "price"를 키값으로 각각의 value를 보여주고 있다. 




4. 간단한 크롤링 예제

 물론 다음 포스팅부터는 JSoup을 이용하여 Java에서 크롤링을 중점적으로 다룰 예정이지만, 오늘은 간단한 맛보기로 이 포스트에서 등장한 사과 가격 정보 수집을 F12를 눌렀을 때 나오는 개발자 도구를 바탕으로 크롤링을 해보자. (이 예제는 크롤링이라기 보다, 크롤링을 어떠한 방법으로 하는지를 보여주는 예제이다.)   


 (1) HTML 사과 정보 크롤링

1.1 Naver 검색창에서 "사과" 검색

1.2 F12를 눌러 개발자 도구 열기

1.3 아래의 코드를 개발자 도구 Console에 붙여넣기.

 var appleInfo = { 
	link : '', price : '', reviews : ''
};
appleInfo.link = document.getElementsByClassName('tit single')[0].getElementsByTagName('a')[0].href;
appleInfo.price = document.getElementsByClassName('dsc price')[0].innerHTML;
appleInfo.reviews = document.getElementsByClassName('dsc compare')[0].getElementsByTagName('em')[0].innerHTML;

appleInfo.price = parseInt(appleInfo.price.replace(',',''));
appleInfo.reviews = parseInt(appleInfo.reviews.replace(',',''));
appleInfo;

    추신 : 위의 코드처럼 짜면 욕먹는다, 단순 예시임을 명심하자.



1.4 출력되는 정보 보기


 



페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사