2022년 4월 8일 금요일

[기록용] 네이버 증권 등에서 받아온 xml 데이터 파싱 ( 주식1)

 Naver 에서 알려져 있는 회사 이름을 검색하면, 쉽게 해당 회사의 주식 정보를 확인할 수 있습니다.  (  Naver 로 검색 )

현재 시점의 사이트는 https://finance.naver.com/item/main.naver?code=035420 으로 간단한 

정보를 확인할 수 있습니다.  ( 향후 어느 시점에 해당 URL은 변경될 수 있습니다. )

해당 메뉴에서 Chart 를 선택하면 다음과 같은 URL 을 확인할 수 있습니다. 

https://finance.naver.com/item/fchart.naver?code=035420

이 화면에 나오는 데이터를 구성하기 위해서 통신한 결과를 확인하여 데이터를 받으면 

주식 데이터를 확인 할 수 있습니다. 


데이터 중에는 

 [['날짜', '시가', '고가', '저가', '종가', '거래량', '외국인소진율'],

["20171120", 161827, 162027, 159425, 160427, 85893, 59.33],

의 배열 처럼 보이는 데이터도 있고, 아래와 같이 xml 로 보이는 데이터도 있습니다. 

<?xml version="1.0" encoding="EUC-KR" ?>

<protocol>

<notice symbol="035420" count="61">

                </notice>

</protocol>


데이터를 크롤링하는 방법은 여러 언어에서 많이 있지만, java 에서는 jsoup 을 활용하면 

어렵지 않게 가져올 수 있습니다.  해당 사이트에 부하를 DDOS 처럼 주지 않게 하려면 sleep 등을 활용하여 가져오는 방식을 조금 천천히 하는 것도 좋을 것 같습니다. 

일단 위와 같은 xml 파일을 가져왔다면, 해당 파일을 파싱하여 데이터를 확인할 수 있을 것 같습니다.


<protocol>

    <chartdata symbol="005930" name="삼성전자" count="100" timeframe="day" 

        precision="0" originaltime="19900103">

        <item data="20211111|69900| |70000|69600|69900|11489122"/>

        ...

    </chartdata>

</protocol>


위 xml 을 파싱하는 초 간단 코드 입니다. 


import java.io.File;

import java.io.IOException;


import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;


import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;


/**

 * @author kskim

 *

 */

public class NhnOHLCXmlHandler extends DefaultHandler {

private boolean isOnlyHeader = false;


@Override

public void startDocument() {

}

@Override

public void endDocument() {

//System.out.println ( "END : " + hDto.getStockName() + " , " + hDto.getPriceDTOSize());

}

@Override

public void startElement(String uri, String localName,

            String qName, Attributes attributes) {

if ( isOnlyHeader ) {

// if ( hDto != null )

// return;

}

if ( qName.equals("chartdata")) {

int cLen = attributes.getLength();

for ( int i = 0; i < cLen; i++ ) {

System.out.println ( i + " , " + attributes.getValue(i) + " , " + attributes.getQName(i));

}

String stockID = attributes.getValue("symbol");

String stockName = attributes.getValue("name");

int dayCount = Integer.parseInt(attributes.getValue("count"));

String nhnTimeFrame = attributes.getValue("timeframe");

int nhnPresision = Integer.parseInt(attributes.getValue("precision"));

String nhnOriginTime = attributes.getValue("origintime");

} else if ( qName.contentEquals("item")) {

String str = attributes.getValue(0);

if ( str != null && str.trim().length() > 0 ) {

str = str.replaceAll("[\\h]", "");

String[] strArray = str.split("\\|");

int cLen = strArray.length;

if ( cLen == 6  ) {

String dayID = strArray[0];

float openPrice = Float.parseFloat(strArray[1]);

float highPrice = Float.parseFloat(strArray[2]);

float lowPrice = Float.parseFloat(strArray[3]);

float closePrice = Float.parseFloat(strArray[4]);

long volumn = Long.parseLong(strArray[5]);

System.out.println ( dayID + " : " + closePrice);

}

}

}

}

@Override

public void endElement(String uri, String localName, String qName) {   

        //System.out.println ( "endElement : " +  uri + " , " + localName + " , " + qName );

    }

public void characters (char ch[], int start, int length) {

//System.out.println ( " characters : " + new String(ch,start,length));

}


/**

* @param args

*/

public static void main(String[] args) {

String baseDir = "위 형식이 담긴 파일.xml";

SAXParserFactory sf = SAXParserFactory.newDefaultInstance();

try {

File f = new File(baseDir);

SAXParser sp = sf.newSAXParser();

NhnOHLCXmlHandler qph = new NhnOHLCXmlHandler();

try {

sp.parse(f, qph);

} catch (IOException e) {

e.printStackTrace();

}

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

}

}

}


개인적으로는 주식에 문외한 입니다.  금융이나, 주식 분석의 영역은 거의 모르는 분야이지만,  개발의 관점에서 데이터 수집, 파싱, 추세 , 분석의 데이터로는 관심이 많아서 조금씩 모듈을 구성해 보고 그 과정을 기록하고자 합니다. 


댓글 없음:

댓글 쓰기