데이터 수집을 위한 크롤링 연속 포스팅 [크롤링] 데이터 수집을 위한 크롤링 1편 : 크롤링이란 무엇인가? [크롤링] 데이터 수집을 위한 크롤링 2편 : 크롤링에 필요한 필수 요소들 [크롤링] 데이터 수집을 위한 크롤링 3편 : JSON, 더 자세한 설명 [크롤링] 데이터 수집을 위한 크롤링 4편 : Java의 설치와 간단한 Jsoup 예제 [크롤링] 데이터 수집을 위한 크롤링 5편 : Yahoo 파이낸스를 이용한 환율 크롤링
1. 크롤링전에 앞서
본격적으로 자신의 목적에 맞는 크롤러를 만들어보자. 이번에 만들 크롤러는 환율 정보를 가져오는 크롤러이다.2. 과정을 나누어 살펴보면..
(1) 대상 선정 우선 우리는 야후 파이낸스의 환율정보를 크롤링할 예정이다. 야후 파이낸스는 https://finance.yahoo.com이며, 클릭해보면 아래와 같은 페이지가 나온다.
대상 선정 과정에서는 환율 정보를 제공하는 페이지를 어떻게 접근할 수 있을지 고민해야한다. 우선 여러가지 화폐가 있겠지만, 간단히 몇가지를 검색해보자.
간단하게 캐나다 달러와 엔화를 검색해보자.
캐나다 달러
엔화
검색한 내용을 쭉 살펴보다보면, 어디쯤에 환률 정보가 있는지 알 수 있다. 또한 우리는 크롤링을 할 예정이므로, 각 환율 정보의 고유 URI인 URL은 https://finance.yahoo.com/quote/XXXKRW=X?p=XXXKRW=X임을 알 수 있다.
이 두가지 정보를 찾았다면, 다음 단계인 데이터 로드로 넘어가자.
(2) 데이터 로드 및 데이터 분석 데이터 로드의 방법에는 여러가지가 있지만, 우선 포스트의 난이도를 낮추기 위해 개발자 모드를 이용해보자.
개발자 모드는 해당 URL에 접근하였을 때 얻을 수 있는 모든 데이터를 보여준다. (개발자 모드는 F12를 이용하여 접근할 수 있다)
우선 개발자 모드의 Elements 탭에서 환율 정보 (아래의 이미지의 1,119.02)를 찾아보자. 찾기 힘들다면, 개발자 모드 좌측 상단 마우스 커서 모양을 클릭하면 HTML과 웹 페이지가 동기화되어, 마우스를 가져간 곳에 하이라이트를 해준다.
마찬가지로, 캐나다 달러에 대해서도 환율 정보가 있는 HTML 부분을 찾아보자.
위와 같이 환율 정보는 HTML에 포함되어 있고, 이 HTML을 우리가 만들 크롤러가 정상적으로 로드할 수 있다면, 다음 과정인 데이터 분석으로 넘어가도록 하자.
앞서 보인 달러와 캐나다 달러의 환율 정보를 담고 있는 HTML태그는 span이다. 또한 공통적으로 data-reactid="35"를 태그 어트리뷰트로 가지고 있다.
이제는 span이면서 어트리뷰트 data-reactid="35"를 가지는 태그가 유일한지 확인하는 절차가 필요하다. 우선 Yahoo 파이낸스에는 jQuery를 사용하고 있어, jQuery로 위와 같은 조건을 가진 Span 태그를 검색해보자.
$('span[data-reactid="35"]') 문법에서 $는 jQuery를 의미하고, 괄호안의 내용은 셀렉터를 의미한다. 셀렉터 안에는 여러가지 문법이 올 수 있는데 span으로 시작하게되면, span이라는 태그를 검색하겠다는 의미이다.
대괄호의 경우 해당 태그중 data-reactid 어트리뷰트가 "35"인 span 가져오겠다는 의미를 가진다. 따라서 이를 검색했을때, 해당 어트리뷰트가 존재한다면 HTML 태그를, 아니라면 undefined를 리턴하게 된다.
Yahoo 파이낸스는 위의 검색 조건을 따르게 된다면 정상적으로 환율 정보를 얻을 수 있다. 이제 간단한 Java 크롤러 예제를 만들어 실제로 크롤러 또한 동일하게 환율 정보를 찾을 수 있는지 확인해보자.
코드 예제 1
위와 같이 정상적으로 달러의 환율 정보를 얻을 수 있으면, 이제 자신이 얻고자하는 통화 코드를 알아야하지 않을까?
코드 예제 1의 자바 코드
import java.io.IOException;
// 예외 처리 임포트
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
// Jsoup 임포트
public class CurrencyCrwaler{
// Jsoup은 예외 처리를 해주어야 합니다.
// 여기서는 getCurrencyRate를 호출한 Caller에서 예외처리를 하도록 throws로 선언합니다.
public static void getCurrencyRate(String cc) throws IOException {
String URL = "https://finance.yahoo.com/quote/"+cc+"?p="+cc;
// URL 정보를 매개변수 cc를 이용해 생성합니다.
Document doc = Jsoup.connect(URL).get();
// Jsoup을 이용하여, 해당 URL을 get 메소드로 로드하여 Document 변수에 담습니다.
Elements elem = doc.select("span[data-reactid=\"35\"]");
// 얻어진 Document에서 Span중 data-reactid 어트리뷰트가 35인 것을 찾습니다.
String str = elem.text();
// 찾아진 엘리먼트(태그)들의 값을 Text로 출력합니다.
System.out.println(str);
}
public static void main(String[] args){
String cc = "USD";
// getCurrencyRate에서 발생하는 예외처리를 받아서 단순 출력 처리합니다.
try {
getCurrencyRate(cc+"KRW=X");
} catch (IOException e) {
e.printStackTrace();
}
}
}
통화 코드는 ISO 4217에 따라서 아래와 같이 정의된다. 더 상세한 내용은 https://ko.wikipedia.org/wiki/ISO_4217 이곳을 참고하여 자신이 얻고자하는 통화 코드를 뽑아내자.
나의 경우는 아래와 같이 여러개의 통화코드를 이용하여 환율 정보를 얻을 예정이다.
USD,JPY,AUD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,GBP,HKD,HUF,IDR,ILS,MXN,MYR,NOK,NZD,PHP,PKR,PLN,RUB,SEK,SGD,THB,TRY,TWD,ZAR,EUR,UAH,INR,ISK,NGN
(4) 데이터 수집
이제 마지막 단계로 위에서 뽑아둔 통화 코드를 바탕으로 환율 정보를 수집해보자.
예제 코드 1에서 우리는 간단하게 현재 값을 얻어내는 함수를 정의했고, 이 함수에 통화코드만 전달해주면 해당 통화의 환율을 콘솔에 출력하도록 하였다.
이제는 한개의 환율을 출력하는 것이 아니라, 배열로 만들어 여러개를 순차적으로 호출하도록 하자.
예제 코드 2
예제 코드 2의 소스코드
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class CurrencyCrwaler{
public static void getCurrencyRate(String cc) throws IOException {
String URL = "https://finance.yahoo.com/quote/"+cc+"?p="+cc;
Document doc = Jsoup.connect(URL).get();
Elements elem = doc.select("span[data-reactid=\"35\"]");
String str = elem.text();
System.out.println(str);
}
public static void main(String[] args){
String ccs = "USD,JPY,AUD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,GBP,HKD,HUF,IDR,ILS,MXN,MYR,NOK,NZD,PHP,PKR,PLN,RUB,SEK,SGD,THB,TRY,TWD,ZAR,EUR,UAH,INR,ISK,NGN";
// 얻고자하는 통화 코드를 문자열로 저장합니다.
String[] ccList = ccs.split(",");
// 저장한 문자열에서 ,(쉼표)단위로 이를 잘라 문자열 배열에 담습니다.
try {
// 문자열 배열을 순회하면서 환율 정보 수집 함수인 getCurrencyRate를 호출합니다.
for(int i = 0 ; i < ccList.length; i++)
getCurrencyRate(ccList[i]+"KRW=X");
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 이제 자신에게 필요한 처리를..
성공적으로 환율 정보를 수집했다면, 이를 자신이 활용할 수 있는 방법으로 저장해야 한다. 가장 간단한 방법은 수집된 시간별로 파일화하여 저장하거나, DBMS에 저장하는 등의 방법을 강구하여야 한다.
또한 크롤링 자체는 크롤링 대상의 서비스가 온전하다는 가정하에 이루어지는 것이기 때문에 항상 서버가 다운되는 등의 예외적인 상황에 대비하여야 한다. 따라서 환율 정보의 경우 크롤링 성공 시간을 같이 저장하여, 이 정보가 언제 갱신되었는지 확인해주는 것이 좋다.
4. 생각보다 너무 간략해서..
원래라면 생각보다 난이도가 높은 크롤링을 진행할 예정이었는데, 생각보다 환율 정보 수집이 너무 간단해서 다른 예제를 가지고 한번 더 진행해야 할 것 같다. 이러면 안되는데.. 다음편 계속.데이터 수집을 위한 크롤링 연속 포스팅 [크롤링] 데이터 수집을 위한 크롤링 1편 : 크롤링이란 무엇인가? [크롤링] 데이터 수집을 위한 크롤링 2편 : 크롤링에 필요한 필수 요소들 [크롤링] 데이터 수집을 위한 크롤링 3편 : JSON, 더 자세한 설명 [크롤링] 데이터 수집을 위한 크롤링 4편 : Java의 설치와 간단한 Jsoup 예제 [크롤링] 데이터 수집을 위한 크롤링 5편 : Yahoo 파이낸스를 이용한 환율 크롤링
'시리즈물 > 데이터 수집을 위한 크롤링' 카테고리의 다른 글
[크롤링] 데이터 수집을 위한 크롤링 4편 : Java의 설치와 간단한 Jsoup 예제 (1) | 2019.03.02 |
---|---|
[크롤링] 데이터 수집을 위한 크롤링 3편 : JSON, 더 자세한 설명 (434) | 2019.03.02 |
[크롤링] 데이터 수집을 위한 크롤링 2편 : 크롤링에 필요한 필수 요소들 (403) | 2019.03.02 |
[크롤링] 데이터 수집을 위한 크롤링 1편 : 크롤링이란 무엇인가? (492) | 2019.03.02 |