728x90

네이버 증권에서 52주 최고 주가를 가져오는 PHP 크롤링 코드를 구현하는 과정을 적어둔다.

 

준비물 : Firefox 브라우저

- 크롬브라우저로 했더니 selector 를 알려주는 결과로 원하는 결과를 얻을 수 없었다.

- 그래서 난 Firefox 브라우저를 활용하기로 했다.

 

1단계 : F12키를 눌러 소스보기 화면을 띄운다.

2단계 : 추적하는 아이콘을 눌러 검색하고자 하는 곳에 마우스로 가져간다.

 

3단계 : table class 가 rwidth 라는 걸 찾았다.

 

 

이제 두번째 tr의 selector 값을 찾는 과정이다.

 

찾은 결과는

.rwidth > tbody:nth-child(2) > tr:nth-child(2)

이다.

 

이걸 기준으로 PHP simpe_html_dom 라이브러리 기준의 코드를 구현하자.

$html->find('table.rwidth tbody:nth-child(2) tr',1)

tr:nth-child(2)는 2번째 tr 을 의미하므로 find 로 찾는 것은 0, 1 이므로 1을 선택하면 된다.

 

tr 하단 DOM 트리 구조에 th 와 td가 있다.

그러므로 find('td',0)

td 트리 하단에 em 이 2개 있다. 여기서 첫번째 이므로 최종적인 코드는 아래와 같다.

 

$html->find('table.rwidth tbody:nth-child(2) tr',1)->find('td',0)->find('em',0);

 

최종 코드는 아래와 같다.

 

<?php
error_reporting(0);
//*
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
// */
 
require_once $_SERVER['DOCUMENT_ROOT'].'/simple_html_dom.php';
 
$code = '036460';
 
    $url = 'https://finance.naver.com/item/main.naver?code=' . $code;
    $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0';
    $options = [
        'http' => [
            'header' => 'User-Agent: ' . $userAgent
        ]
    ];
 
    $context = stream_context_create($options);
    $html = file_get_html($urlfalse$context);
 
    if ($html) {
        // 52주 고가
        $maxElement = $html->find('table.rwidth tbody:nth-child(2) tr',1)->find('td',0)->find('em',0);
        $stock_52maxVal = preg_replace('/[^0-9]/'''$maxElement->plaintext);
 
        header('Content-Type: text/html; charset=utf-8');
        echo $stock_52maxVal.'<br/>';
 
    } else {
        echo 'Failed to retrieve the data';
    }
 
 
?>
 

 

 

 

 

728x90
블로그 이미지

Link2Me

,
728x90

네이버 증권 일별 시세를 PHP 로 크롤링하는 코드 예제이다.

 

<?php
error_reporting(0);
//*
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
// */
 
require_once $_SERVER['DOCUMENT_ROOT'].'/simple_html_dom.php';
 
$code = '039610';
$page = 1;
 
// 함수화할 영역으로 3페이지(1개월)부터 역순으로 DB 저장을 해야 최신 자료가 위로 저장된다.
$url = 'https://finance.naver.com/item/sise_day.naver?code=' . $code . '&page=' . $page;
 
// 웹페이지에서 HTML 데이터 가져오기
$ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
$options = [
    "http" => [
        "header" => "User-Agent: " . $ua
    ]
];
$context = stream_context_create($options);
$html = file_get_html($urlfalse$context);
 
if ($html) {
    $items = $html->find('.type2 tbody:nth-child(3) tr[onmouseover="mouseOver(this)"]');
 
    $stockDayTemp = [];
    foreach($items as $item) {
        $info = [];
        foreach($item->find('td'as $td) {
            $info[] = trim($td->plaintext);  // <td> 내부 텍스트를 추출하여 배열에 저장
        }
        //echo '<pre>';print_r($info);echo '</pre>';
        $sdate = preg_replace('/[^0-9\.]/'''$info[0]); // 날짜
        $closeM = preg_replace('/[^0-9]/'''$info[1]); // 종가
        $openM = preg_replace('/[^0-9]/'''$info[3]); // 시가
        $highM = preg_replace('/[^0-9]/'''$info[4]); // 고가
        $lowM = preg_replace('/[^0-9]/'''$info[5]); // 저가
        $volume = preg_replace('/[^0-9]/'''$info[6]); // 거래량
 
        $cv30 = floatval($closeM* 1.3// 상한가
        $cv60 = floatval($closeM* 1.6// 단기 투경 기준
        $cv100 = floatval($closeM* 2// 4주 투경 기준
 
        $stockDayTemp[] = [
            $code$sdate$closeM$openM$highM$lowM$volume$cv30$cv60$cv100
        ];
    
    }
 
    foreach (array_reverse($stockDayTempas $items) {
        echo '<pre>';print_r($items);echo '</pre>';
    }
 
}
?>

 

 

728x90
블로그 이미지

Link2Me

,
728x90

네이버 증권 오늘 날짜, 종가 및 고가 정보를 크롤링하는 PHP 코드이다.

 

<?php
error_reporting(0);
//*
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
// */
 
require_once $_SERVER['DOCUMENT_ROOT'].'/simple_html_dom.php';
 
$code = '001740';
 
 
    $url = "https://finance.naver.com/item/main.naver?code=".$code;
 
    // 웹페이지에서 HTML 데이터 가져오기
    $ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
    $options = [
        "http" => [
            "header" => "User-Agent: " . $ua
        ]
    ];
    $context = stream_context_create($options);
    $html = file_get_html($urlfalse$context);
    $enc = mb_detect_encoding($htmlarray('EUC-KR''UTF-8''shift_jis''CN-GB')); // HTML의 인코딩을 감지
    if ($enc != 'UTF-8') { // 감지된 인코딩이 UTF-8이 아닌 경우 변환
        $html = iconv($enc'UTF-8'$html);
    }
    $html = str_get_html($html);
 
    if ($html !== false) {
 
        $stock_day = $html->find('div.description #time em.date',0)->plaintext;
        $date_today = substr($stock_day,0,10);
 
        $stock_curval = $html->find('#chart_area div.rate_info p.no_today',0);
 
        if ($stock_curval) { 
            $stock_close = $stock_curval->find('em.no_up span'0); // 종가 상승
 
            if (!$stock_close) { 
                $stock_close = $stock_curval->find('em.no_down span'0); // 종가 하락
            }
            
            if (!$stock_close) {
                $stock_close = $stock_curval->find('span.blind'0); // 종가 보합
            }
 
            if ($stock_close) {
                $close = preg_replace("/[^0-9]/"""$stock_close->plaintext); // 오늘의 종가
            }
        }
 
        $stock_hval = $html->find('#chart_area div.rate_info table tr td:nth-child(2)',0);
        if ($stock_hval) { 
            $stock_high = $stock_hval->find('em.no_up span'0); // 고가 상승
 
            if (!$stock_high) { 
                $stock_high = $stock_hval->find('em.no_down span'0); // 고가 하락
            }
            
            if (!$stock_high) {
                $stock_high = $stock_hval->find('span.blind'0); // 종가 보합
            }
 
            if ($stock_high) {
                $todayHigh = preg_replace("/[^0-9]/"""$stock_high->plaintext); // 오늘의 고가
            }
        }
 
        echo $date_today.'<br/>';
        echo $close.'<br/>';
        echo $todayHigh.'<br/>';
 
    }
?>

 

 

728x90
블로그 이미지

Link2Me

,
728x90

네이버 증권에서 최대주주 지분율을 가져오는 코드를 구현해보자.

 

위 보유지분을 일일이 확인하기 귀찮아서 구현한 코드이다.

 

<?php
error_reporting(0);
//*
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
// */
 
ini_set('max_execution_time'0);
ini_set('memory_limit','-1'); // 메모리 무제한으로 늘리기
 
require_once 'simple_html_dom.php';
 
$code = '142280';
 
    // Naver Finance URL 생성
    $url = 'https://finance.naver.com/item/coinfo.naver?code=' . $code;
 
    // 웹페이지에서 HTML 데이터 가져오기
    $ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
    $options = [
        "http" => [
            "header" => "User-Agent: " . $ua
        ]
    ];
    $context = stream_context_create($options);
    $html = file_get_html($urlfalse$context);
 
    if ($html !== false) {
        // iframe을 찾아서 src 속성 값을 가져온다.
        $frame = $html->find('iframe#coinfo_cp'0);
        if ($frame) {
            $frameaddr = $frame->src;
 
            // iframe에서 HTML 데이터 가져오기
            $frame_html = file_get_html($frameaddrfalse$context);
 
            if ($frame_html !== false) {
                // 특정 클래스를 가진 모든 <td> 요소를 찾는다.
                $coinfo = $frame_html->find('#cTB13 > tbody tr td.noline-right.num');
 
                // 합계 변수 초기화
                $sum = 0;
 
                foreach ($coinfo as $val) {
                    $info = trim($val->plaintext);
                    if ($info !== '') {
                        // 문자열을 숫자로 변환하여 합계에 추가
                        $info = floatval($info);
                        $sum += $info;
                    }
                }
                echo $sum// 이걸 확인한다. 필요시 DB 저장하는 코드를 추가하면 된다.
 
            } else {
                echo 'Failed to retrieve iframe content';
            }
        } else {
            echo 'Failed to find iframe';
        }
    } else {
        echo 'Failed to retrieve main content';
    }
 
?>
 

 

Python 으로 구현했던 코드를 chatGPT에 PHP코드로 변환해 달라고 했더니 변환해주었다.

약간의 오류를 수정하고 원하는 결과를 얻었다.

PHP로 구현했던 함수를 Python 으로 변경 요청하면 제대로 동작이 안되는 경우가 많아 이기종 언어간에 변환은 크게 기대하지 않았었다.

PHP 와 Python 을 접목하여 사용했었는데 이 코드로 Python을 별도 설치하지 않고 해결할 수 있어 편하다.

 

위 코드에서 치명적인 단점은 한글 인식을 못한다는 것이다.

몇차례 chatGPT에 해결책을 요구했으나 끝내 해결되지 않아서 내가 해결책을 제시해줬다.

    $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0';
    $options = [
        'http' => [
            'header' => 'User-Agent: ' . $userAgent
        ]
    ];
 
    $context = stream_context_create($options);
 
    $html = file_get_html($urlfalse$context);
 
    // HTML의 인코딩을 감지
    $enc = mb_detect_encoding($htmlarray('EUC-KR''UTF-8''shift_jis''CN-GB'));
 
    // 감지된 인코딩이 UTF-8이 아닌 경우 변환
    if ($enc != 'UTF-8') {
        $html = iconv($enc'UTF-8'$html);
    }
 
    $html = str_get_html($html);

 

 

 

728x90
블로그 이미지

Link2Me

,