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

관심종목 : 0130

투자자별 매매동향 : 0796

투자바별 매매동향 : 0795

장중투자자별매매 : 1052

 

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

,

MariaDB 경로 변경

SQL 2024. 8. 8. 07:41
728x90

mariadb의 공간 부족으로 인해 경로를 변경하는 방법이다.

 

먼저 할당된 공간을 확인한다.

 

기본으로 mariadb가 설치되는 경로는 /var/lib/mysql 이다.

 

공간이 home 디렉토리에 비해 상대적으로 적다.

공간이 충분한 home 디렉토리 하단으로 옮기겠다.

 

 

# 1) MariaDB 서비스 정지
sudo systemctl stop mariadb
 
# 2) 새로운 Data 디렉토리 생성 및 데이터 복사하기
# Data 디렉토리를 /home/data/mysql 로 한다고 할 때
 
sudo mkdir /home/data/
sudo rsync -av /var/lib/mysql /home/data/
sudo chown -R mysql:mysql /home/data/mysql
 
# 3) 서버 설정 파일 변경
vi /etc/my.cnf.d/server.cnf
[mysqld]
datadir=/home/data/mysql
socket=/home/data/mysql/mysql.sock
log-error=/home/data/mysql/error.log
 
[client]
port=3306
socket=/home/data/mysql/mysql.sock
 
4) MairaDB /root /home 디렉토리 접근 허용하여 ProtectHome true 를 false 로 변경한다.
vi /usr/lib/systemd/system/mariadb.service
ProtectHome=false 
#wq

 

 

위와 같이 경고 메시지가 나와도 다음 단계를 진행하면 정상적으로 처리된다.

 

5) mariadb 실행하면 경고 메시지가 출력된다.
systemctl start mariadb
 
6) reload
systemctl daemon-reload
 
7) 최종 서비스 시작
systemctl start mariadb
 
8) 데이터 디렉토리 위치 변경 확인
mysql -u root -p
 
MariaDB [(none)]> select @@datadir;
 
9) 기존 mysql 폴더 bak 폴더로 변경하기
sudo mv /var/lib/mysql /var/lib/mysql.bak

 

경로가 변경된 것을 확인할 수 있다.

 

 

728x90
블로그 이미지

Link2Me

,