• 윈도우7에서 셀레니움과 파이썬으로 HTTPS 다운로드 완벽 가이드

    윈도우7에서 셀레니움과 파이썬으로 HTTPS 다운로드 완벽 가이드

    윈도우7에서 셀레니움과 파이썬으로 HTTPS 이미지 자동 다운로드 완벽 가이드

    크롬드라이버, requests, TLS 1.2 패치까지 한 번에 해결하는 실전 자동화 노하우

    요약

    • 윈도우7에서 최신 HTTPS 이미지를 파이썬으로 자동 다운로드하려면 TLS 1.2 패치크롬드라이버-브라우저 버전 일치가 필수입니다.
    • 셀레니움으로 최종 이미지 URL을 확인 후, requests로 안정적으로 다운로드합니다.
    • 방화벽/프록시/네트워크 환경과 User-Agent, 헤더까지 모두 고려한 실전 예제 코드를 제공합니다.

    사전 준비

    1. 크롬 브라우저와 크롬드라이버 109 이하 버전 설치 및 경로 확인
    2. 윈도우7 TLS 1.2 패치(KB3140245) 적용 및 재부팅
    3. 파이썬 3.8 이상, selenium, requests 패키지 설치
    4. 네트워크 방화벽/프록시 정책 확인

    1단계: 환경 점검 및 패치

    • 윈도우7에서 최신 HTTPS 사이트 접속이 안 될 경우 KB3140245 패치와 레지스트리 설정으로 TLS 1.2 활성화
    • 방화벽/백신에서 python.exe, chromedriver.exe 예외 처리
    • 회사/기관 네트워크라면 프록시 주소 확인

    2단계: 크롬드라이버와 브라우저 버전 일치

    • 크롬 브라우저 버전 확인: chrome://version/
    • 같은 버전의 크롬드라이버 다운로드 및 경로 지정
    • 드라이버 경로와 브라우저 버전이 다르면 오류 발생

    3단계: 셀레니움과 requests 통합 코드

    
    import os
    import requests
    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.chrome.options import Options
    
    CHROMEDRIVER_PATH = r"C:\_자료실\티온\로보프레스 PY\chromedriver.exe"
    IMG_URL = "https://www.rand3.com/wp-content/uploads/2025/04/EC868CEC8381EAB3B5EC9DB8ECA780EC9B90EAB888_3.jpg"
    SAVE_PATH = "최종_다운로드_이미지.jpg"
    
    chrome_options = Options()
    chrome_options.add_argument("--headless=new")
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--window-size=1920,1080")
    chrome_options.add_argument("--lang=ko-KR")
    chrome_options.add_argument(
        "user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/109.0.5414.120 Safari/537.36"
    )
    
    service = Service(CHROMEDRIVER_PATH)
    driver = webdriver.Chrome(service=service, options=chrome_options)
    driver.get(IMG_URL)
    final_img_url = driver.current_url
    driver.quit()
    
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/109.0.5414.120 Safari/537.36",
        "Accept-Language": "ko-KR,ko;q=0.9",
        "Referer": "https://www.rand3.com/"
    }
    
    response = requests.get(final_img_url, headers=headers, timeout=20, verify=False)
    if response.status_code == 200:
        with open(SAVE_PATH, "wb") as f:
            f.write(response.content)
        print(f"[다운로드 성공] 저장 위치: {os.path.abspath(SAVE_PATH)}")
    else:
        print(f"[실패] HTTP 상태 코드: {response.status_code}")
          
    • headless 모드GPU 옵션 적용
    • User-Agent, Referer 등 브라우저와 동일하게 설정
    • requests로 최종 이미지 다운로드 (프록시/방화벽 환경은 별도 설정 필요)

    SEO 최적화 포인트

    • <title> 태그는 60자 이내, 핵심 키워드를 맨 앞에 배치
      예시: <title>윈도우7 셀레니움 HTTPS 이미지 자동 다운로드 가이드</title>
    • <meta name=”description”>은 160자 이내, 요약문과 키워드 포함
    • H1~H3 등 헤딩 태그로 논리적 구조화, 각 단계에 키워드 포함
    • 코드와 단계별 절차는 리스트/ol/ul 태그로 구조화
    • 이미지 alt 속성에 키워드 포함 (예: <img src="..." alt="윈도우7 HTTPS 이미지 자동 다운로드">)
    • 불필요한 inline 스타일, 중복 태그 최소화로 HTML 최적화

    © 2025 문호영. 자동화와 플랫폼 개발을 위한 실전 가이드.

  • NAT LINUX IP MATCHING DDNS 서버 구축

    NAT LINUX IP MATCHING DDNS 서버 구축

    NAT LINUX

    NAT LINUX

    IP MATCHING is just match

    낫리눅스 생성방법

    1. 가상스위치 NAT 생성

    2. 포트 그룹 NAT 생성

    3. ___NAT_TVM7 업로드

    3.1. ___NAT_TVM7 네트워크 연결 – (1)항목에 생성한 가상 스위치 NAT

    4. ___NAT_LINUX 업로드

    4.1. ___NAT_LINUX 네트워크 연결 – (3.1)항목에 연결된 가상 스위치 NAT

    5. ___NAT_TVM7 새로운 네트워크 추가

    6. ___NAT_TVM7 네트워프 NAT 설정 및 HOSTNAME 등록

    7. crontab -e

    7. 81 MONITOR CHECKED!!

    DDNS 서버 구축

    DDNS 서버 구축완료!

    DDNS 서버를 구축하기 위해서는 2가지만 알면된다.

    DNS서버의 개념과 클라이언트 서버의 IP를 어떻게든 프로그램이든 뭐든 이용해서 자동으로 알아낼 수 있으면 된다.

    내 경우에는 윈도우즈와 NAT서비스를 이용하여 리눅스 서버의 IP를 자동으로 수집하도록 만들었다.

    그리하여 2개의 OS (WINDOWS, LINUX) 만 존재하면 자동으로 서버 IP를 유지할 수 있다.

    정말 재미있는 사실은…

    이 글을 나 이외 아무도 이해를 못한다는 점이다.

    그래서 이 시스템구축 분야는 블루오션이 아니라 독점분야라는것이다.


  • 파이썬 파싱 추출 pip install 명령어

    파이썬 파싱 추출 pip install 명령어

    파이썬 파싱

    반복 체크

    1분마다 데몬 체크

    1초마다 실행 프로세서 체크

    mkdir /var/www/_______API

    cd /var/www/_______API

    mkdir /var/www/_______API
    cd /var/www/_______API
    
    pip install requests
    pip install urllib3
    pip install "urllib3<2"
    pip install bs4
    pip install mysql-connector-python
    yum update -y
    
    crontab -e
    */1 * * * * /var/www/_______API/_monitor_PY.sh


    명령어 준수

    사용중인 서버

    02110002

    02280001

    10013801

    10013802

    10013803

    10013804

    JUST

    BLOG SYSTEM CONSTRUCTION

    ___NAT_LINUX MODELs

  • 워드프레스 업로드 용량 서버 사진 이미지 2MB 제한 해제

    워드프레스 업로드 용량 서버 사진 이미지 2MB 제한 해제

    이미지 업로드 용량 해제하는 방법입니다

    워드프레스 서버 이미지 업로드 용량 해제 방법

    업로드 용량

    스니핏 소스코드

    // PHP 설정 변경 함수
    function set_custom_upload_limits() {
        @ini_set('upload_max_filesize', '8192M');
        @ini_set('post_max_size', '8192M');
        @ini_set('max_execution_time', '1200');
        @ini_set('max_input_time', '1200');
    }
    // init 액션에 함수 연결 (우선순위 1로 설정)
    add_action('init', 'set_custom_upload_limits', 1);
    

    소스를 그대로 복사하여 스니핏 새로 만들어 추가하면됩니다.

    이 스니핏도 관리자에만 등록해서 사용해도 될꺼같다는 생각도 드네요.

    위의 소스코드가 동작하지 않을 경우 아래 링크에서 새로운 버전으로 설치해보세요.

    스니핏 업로드 할때 용량 제한 해제

    새로운 스니핏은 소스코드가 다릅니다.

    기존의 방식과 다르게 .haccess 파일을 직접 쓰고 수정합니다.

    그래서 .haccess 파일을 제어할 수 있어야 합니다.

    수정, 삭제, 생성 권한이 있어야 합니다.

    업로드 용량 해제 스니핏

    이외 유용한 스니핏 모음

  • 워드프레스 마우스 오른쪽 버튼 키보드 복사 방지 1분 만들기

    워드프레스 마우스 오른쪽 버튼 키보드 복사 방지 1분 만들기

    워드프레스 마우스 오른쪽 버튼

    워드프레스 마우스 오른쪽 버튼 복사 방지 방법

    오른쪽 마우스 클릭 방지

    새로운 버전이 올라왔으니 모든 스니핏은 아래 링크를 통해 업데이트 받으시고 설명서도 함께 확인하시기 바랍니다.

    설치 방법도 아래 링크 확인하세요

    블로그 복사 방지 마우스 오른쪽 클릭 방지

    스니핏 소스코드

    add_action('wp_footer', function() {
        // 현재 로그인한 사용자가 관리자가 아닌 경우에만 스크립트 실행
        if (!current_user_can('manage_options')) { 
    ?>
    <!-- Insert Footers START -->
    
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
    jQuery(document).ready(function($) {
        // 마우스 오른쪽 클릭 차단
        $(document).on('contextmenu', function(e) {
            e.preventDefault();  // 기본 동작 방지
        });
    
        // 마우스 드래그로 텍스트 선택 방지 (단, 입력 상자와 텍스트 영역 제외)
        $(document).on('mousedown', function(e) {
            if (e.target.nodeName !== "INPUT" && e.target.nodeName !== "TEXTAREA") {
                e.preventDefault();  // 기본 동작 방지
            }
        });
    
        // Ctrl + C, Ctrl + A 단축키 감지
        $(document).on('keydown', function(e) {
            if (e.ctrlKey && (e.keyCode == 67 || e.keyCode == 65)) {  // Ctrl + C or Ctrl + A
                
                // Ctrl + C를 눌렀을 때 선택한 텍스트가 있으면 출처 추가 후 복사
                if (e.keyCode == 67 && window.getSelection().toString().length > 0) {
                    var originalText = window.getSelection().toString();  // 현재 선택된 텍스트
                    var appendText = ' 출처: ' + window.location.href;  // 현재 페이지 URL을 출처로 추가
                    var newCopyText = originalText + appendText;  // 원본 텍스트에 출처 추가
                    navigator.clipboard.writeText(newCopyText);  // 클립보드에 새 텍스트 저장
                    e.preventDefault();  // 기본 복사 동작 방지
    
                // Ctrl + A를 눌렀을 때 텍스트 선택 방지
                } else if (e.keyCode == 65) {
                    e.preventDefault();  // 기본 동작 방지
                }
            }
        });
    });
    </script>
    
    <!-- Insert Footers END -->
    <?php 
        }
    });
    

    소스를 그대로 복사하여 스니핏 새로 만들어 추가하면됩니다.

    관라자 로그인시 동작하지 않으니 혹시 안된다고 그러시면 안됩니다. ㅎㅎ

    워드프레스 마우스 오른쪽 버튼

    이외 유용한 스니핏

  • DDoS 방어 스니핏 PHP 소스코드 1분 10회공격 IP차단

    DDoS 방어 스니핏 PHP 소스코드 1분 10회공격 IP차단

    이 글은 이 문장을 제외한 모든 문장은 챗GPT로 DDoS 방어 글을 작성되었습니다.

    이러한 기능을 WordPress에 구현하려면 WordPress 플러그인을 만들거나 WordPress 테마 기능.php 파일에 코드를 추가할 수 있습니다.

    아래는 WordPress의 functions.php 파일에 추가할 수 있는 간단한 코드의 예입니다. 이 코드는 사용자의 IP 주소와 액세스 시간을 세션에 저장하고, 동일한 페이지나 파일에 1분에 10번 이상 액세스하는 사용자의 IP 주소를 차단합니다.

    DDoS 방어

    function check_and_block_repeated_requests() {
        session_start();
        
        $user_ip = $_SERVER['REMOTE_ADDR'];
        $current_page = $_SERVER['REQUEST_URI'];
    
        $key = $user_ip . '_' . $current_page;
    
        if (!isset($_SESSION[$key])) {
            $_SESSION[$key] = array('timestamp' => time(), 'count' => 0);
        }
    
        // Check if user has accessed the page within the last 60 seconds
        if (time() - $_SESSION[$key]['timestamp'] < 60) {
            $_SESSION[$key]['count'] += 1;
        } else {
            $_SESSION[$key] = array('timestamp' => time(), 'count' => 0);
        }
    
        // If user accessed the page more than 10 times in the last 60 seconds, block them
        if ($_SESSION[$key]['count'] > 10) {
            die('You have been temporarily blocked due to excessive requests.');
        }
    }
    
    add_action('init', 'check_and_block_repeated_requests');
    
    
    

    현재 WordPress에서 활성화된 function.php 파일에 이 코드를 추가할 수 있습니다.

    참고:

    이 코드는 세션을 사용하여 사용자 액세스 수를 추적합니다. 일부 WordPress 환경에서는 세션 설정이 필요할 수 있습니다.
    위 코드는 예제일 뿐이며 프로덕션 배포를 위해 테스트 및 검증이 필요합니다.
    이러한 기능은 웹 서버, CDN 또는 WAF 수준에서도 구현할 수 있으며 보다 효과적입니다.

  • Google의 시스템이 컴퓨터 네트워크에서 비정상적인 트래픽을 감지했습니다.

    Google의 시스템이 컴퓨터 네트워크에서 비정상적인 트래픽을 감지했습니다.

    Google의 시스템이 컴퓨터 네트워크에서 비정상적인 트래픽을 감지했습니다.

    Google의 시스템이 컴퓨터 네트워크에서 비정상적인 트래픽을 감지했습니다.

    구글에서 파싱을 하려고 하는 프로그래머들이 가장 먼저 겪는 고난? 중 난제거리일겁니다.

    VPN, 혹은 프로그램을 이용한 매크로방식의 반복이거나 특정시간동안 빠른 검색이 일어날 경우 발생하는 메시지입니다.

    해결방법은 그냥 사람인증을 해주면 되지만

    Google의 시스템이 컴퓨터 네트워크에서 비정상적인 트래픽을 감지했습니다. 해결방법

    처음 말한것처럼 프로그래머가 구글 검색을 하여 데이터를 수집하기 위한 목적의 웹파싱을 해야한다면

    당장 답은 캐시 삭제와 IP 변경뿐이다.

    이미 구글 서버에 IP와 HTTP-AGENT를 수집한 상태이므로 당분간은 관리대상IP로 빠지게된다.

    이럴땐 빠르게 IP교체와 캐시삭제를 해서 사용해야하지만 이때에도 주의할 점이 있다.

    과거에는 이러한 방법이 쉽게 먹혔지만

    고도화된 알고리즘에서는 그 프러그래머가 IP를 바꿔서 같은 PC로 할껄 예상하여

    그 PC만의 고유정보를 모두 기록해놓는다.

    그 방법으로 IP와 캐시, 지역, 컴퓨터이름, 맥어드레스 등등이다.

    특히 맥 어드레스의 경우에는 웹 수집이 불가능하지만 요즘에는 크롬브라우저 등 이미 구글 자사 툴이 우리 PC에 많이 설치가되어져있다보니 그냥 싹다 털린다 보면된다.

    결국 당신이 프로그래머라면?

    IP교체와 쿠키삭제로 끝내지말고

    그냥 처음부터 접근방법이 틀린것이다.

    VMWARE -> 윈도우 인스턴스 생성 -> IP 유동으로 받아서 잘 돌리고 ‘시스템이 컴퓨터 네트워크에서 비정상적인 트래픽을 감지했습니다.’ 문구 나오면 삭제 -> VM 새 인스턴스 생성 -> 무한반복 사용

    이때 최적의 딜레이 타임을 알아야한다.

    1분~5분 사이에 잘 찾기 바란다.

    리눅스맨에게 물어보았다.

    구글에서 무슨 프로그램으로 검색할때 이러한 오류현상이 자주 나오는가요?

    당연히 webClient 를 무작위로 돌릴때 가장심하게 그리고 가장 빠르게 이러한 문구를 보게 될것이다.

    프로그래머의 결론은 IP가 많아야 하며 VPN을 사용하면 안된다.

    물론 VPN을 이용하여 우회하거나 피할 수 있지만 근본적으로 구글, 유튜브, 네이버 같은 공룡을 맞이하기에는 역부족일것이다.

    일반사람일경우

    일반인일경우에는 반복하는 프로그램(매크로) 요소만 제거하면 된다.

    아울러 VPN같은 툴을 사용하여 토렌트를 하고 있다면 즉각 해제하여 검색해보기 바란다.

    게임을 위한 VPN 설치도 있지만 단순히 구글 검색을 위해 VPN설치 하는 경우는 드물것이다.

    구글 검색이 주 목적이라면 사용중인 VPN이나 프록시 서버를 해제하기 바란다.

  • 티스토리 애드센스 고수익 블로그 찾는 소스코드 – part 1

    티스토리 애드센스 고수익 블로그 찾는 소스코드 – part 1

    티스토리 애드센스 고수익 블로그

    티스토리 애드센스 고수익 블로그

    티스토리 주소를 모두 수집부터 해야하니 1단계는 수집하는 방법에 대해서 기술합니다.

    각 프로그래밍 언어별로 네이버 사이트 검색을 통하여 티스토리 도메인을 찾아내는것이 part 1의 기술적인 내용입니다.

    티스토리 애드센스 고수익 블로그

    티스토리 애드센스 고수익 블로그 찾는 소스코드

    URL 파라미터값이 반복적으로 달라질 경우 각 언어별로 제어하는 방법입니다

    start 매개변수의 값은 1씩 증가하며, page 매개변수는 start 값을 기반으로 계산

    반복되는 파라미터 값의 URL
    
    https://search.naver.com/search.naver?nso=&page=2&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start=1&where=web
    
    https://search.naver.com/search.naver?nso=&page=3&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start=16&where=web
    
    https://search.naver.com/search.naver?nso=&page=4&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start=31&where=web
    
    https://search.naver.com/search.naver?nso=&page=5&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start=46&where=web

    아래는 각 언어별 위의 URL을 파씽할 수 있도록 C# 소스코드입니다

    C#
    
    using System;
    
    public class Program
    {
        public static void Main()
        {
            int startNumber = 1;
            int endNumber = 5;
    
            string baseUrl = "https://search.naver.com/search.naver?nso=&page={0}&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start={1}&where=web";
    
            for (int number = startNumber; number <= endNumber; number++)
            {
                string url = string.Format(baseUrl, number, CalculateStartValue(number));
                Console.WriteLine(url);
            }
        }
    
        public static int CalculateStartValue(int pageNumber)
        {
            return (pageNumber - 1) * 15 + 1;
        }
    }
    
    나온 URL을 바탕으로 페이지 파씽하는 소스코드
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text.RegularExpressions;
    
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://example.com"; // 파싱할 웹 페이지 URL
            string pattern = @"(tistory\.com)"; // 추출할 문자열 패턴
    
            List<string> list_tistory = new List<string>();
    
            try
            {
                using (WebClient client = new WebClient())
                {
                    string html = client.DownloadString(url); // 웹 페이지의 HTML 가져오기
    
                    // 정규식 패턴을 사용하여 "tistory.com" 문자열 추출
                    MatchCollection matches = Regex.Matches(html, pattern);
                    foreach (Match match in matches)
                    {
                        string tistory = match.Value;
                        if (!list_tistory.Contains(tistory))
                        {
                            list_tistory.Add(tistory);
                        }
                    }
                }
    
                // 중복 없이 추출된 "tistory.com" 문자열 출력
                foreach (string tistory in list_tistory)
                {
                    Console.WriteLine(tistory);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
        }
    }
    
    

    자바스크립트 소스코드

    JAVASCRIPT
    
    function generateURLs(startNumber, endNumber) {
      var baseUrl = "https://search.naver.com/search.naver?nso=&page={0}&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start={1}&where=web";
      
      for (var number = startNumber; number <= endNumber; number++) {
        var startValue = calculateStartValue(number);
        var url = baseUrl.replace("{0}", number).replace("{1}", startValue);
        console.log(url);
      }
    }
    
    function calculateStartValue(pageNumber) {
      return (pageNumber - 1) * 15 + 1;
    }
    
    // 예제 실행
    generateURLs(2, 5);
    
    
    나온 URL을 바탕으로 페이지 파씽하는 소스코드
    
    
    const url = 'http://example.com'; // 파싱할 웹 페이지 URL
    const pattern = /tistory\.com/g; // 추출할 문자열 패턴
    
    const list_tistory = [];
    
    fetch(url)
      .then(response => response.text())
      .then(html => {
        const matches = html.match(pattern);
        if (matches) {
          const uniqueMatches = new Set(matches);
          uniqueMatches.forEach(match => list_tistory.push(match));
    
          // 중복 없이 추출된 "tistory.com" 문자열 출력
          list_tistory.forEach(tistory => {
            console.log(tistory);
          });
        }
      })
      .catch(error => console.error(error));
    

    php 소스코드

    PHP
    
    <?php
    function generateURLs($startNumber, $endNumber) {
      $baseUrl = "https://search.naver.com/search.naver?nso=&page={0}&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start={1}&where=web";
      
      for ($number = $startNumber; $number <= $endNumber; $number++) {
        $startValue = calculateStartValue($number);
        $url = str_replace(["{0}", "{1}"], [$number, $startValue], $baseUrl);
        echo $url . "\n";
      }
    }
    
    function calculateStartValue($pageNumber) {
      return ($pageNumber - 1) * 15 + 1;
    }
    
    // 예제 실행
    generateURLs(2, 5);
    ?>
    
    
    나온 URL을 바탕으로 페이지 파씽하는 소스코드
    
    
    <?php
    $url = 'http://example.com'; // 파싱할 웹 페이지 URL
    $pattern = '/tistory\.com/'; // 추출할 문자열 패턴
    
    $list_tistory = [];
    
    $html = file_get_contents($url);
    if ($html !== false) {
        preg_match_all($pattern, $html, $matches);
        if (!empty($matches[0])) {
            $uniqueMatches = array_unique($matches[0]);
            $list_tistory = array_merge($list_tistory, $uniqueMatches);
    
            // 중복 없이 추출된 "tistory.com" 문자열 출력
            foreach ($list_tistory as $tistory) {
                echo $tistory . "\n";
            }
        }
    }
    ?>
    

    JAVA 언어 소스코드

    JAVA
    
    public class URLGenerator {
      public static void main(String[] args) {
        int startNumber = 2;
        int endNumber = 5;
        generateURLs(startNumber, endNumber);
      }
      
      public static void generateURLs(int startNumber, int endNumber) {
        String baseUrl = "https://search.naver.com/search.naver?nso=&page={0}&qdt=-1&query=%EC%A0%95%EB%B6%80%EC%A7%80%EC%9B%90%EC%84%9C%EB%AF%BC%EB%8C%80%EC%B6%9C+tistory.com&qvt=-1&sm=tab_pag&start={1}&where=web";
        
        for (int number = startNumber; number <= endNumber; number++) {
          int startValue = calculateStartValue(number);
          String url = baseUrl.replace("{0}", Integer.toString(number)).replace("{1}", Integer.toString(startValue));
          System.out.println(url);
        }
      }
      
      public static int calculateStartValue(int pageNumber) {
        return (pageNumber - 1) * 15 + 1;
      }
    }
    
    
    나온 URL을 바탕으로 페이지 파씽하는 소스코드
    
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Main {
        public static void main(String[] args) {
            String url = "http://example.com"; // 파싱할 웹 페이지 URL
            String pattern = "(tistory\\.com)"; // 추출할 문자열 패턴
    
            List<String> list_tistory = new ArrayList<>();
    
            try {
                URL urlObj = new URL(url);
                BufferedReader reader = new BufferedReader(new InputStreamReader(urlObj.openStream()));
                StringBuilder stringBuilder = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    stringBuilder.append(line);
                }
                reader.close();
    
                String html = stringBuilder.toString();
    
                Pattern regex = Pattern.compile(pattern);
                Matcher matcher = regex.matcher(html);
    
                Set<String> uniqueMatches = new HashSet<>();
                while (matcher.find()) {
                    String tistory = matcher.group(1);
                    if (!uniqueMatches.contains(tistory)) {
                        list_tistory.add(tistory);
                        uniqueMatches.add(tistory);
                    }
                }
    
                // 중복 없이 추출된 "tistory.com" 문자열 출력
                for (String tistory : list_tistory) {
                    System.out.println(tistory);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    이렇게 숫자 1부터 100을 입력 할 경우 1페이지부터 100페이지까지 URL을 만들어줍니다.

    나온 URL을 바탕으로 각 페이지를 파씽하면 원하는 항목을 추출할 수 있습니다.

    다음 시간에는 추출한 리스트를 데이터베이스에 입력하는 시간을 만들어보도록 하겠습니다.

    티스토리 블로그 애드센스 고수익내고 계신분들이 자신의 도메인을 꽁꽁 숨겨서 유튜브에서 활동하시는것 같아.

    이왕 오픈할꺼면 도메인도 함께 스스로 오픈 하길 바라는 마음으로 알고리즘을 만들어보았습니다.

    이를 컨텐츠화 시켜서 유튜브로 영상각을 만들고 싶지만… 그런 목적이 아닌

    우리도 고수들 돈 많이 버는 사람들을 따라할수 있도록 하는것이 주 목표입니다.

    듣고 보는것보다

    직접 그들의 티스토리를 똑같이 작성해보는것이 가장 빠른 길이니깐요.

  • 워드프레스 쿠팡 스니펫 플러그인

    워드프레스 쿠팡 스니펫 플러그인

    [쿠팡][/쿠팡] 함수는 상품 링크를 생성하는 데 사용됩니다. 

    함수에는 세 개의 파라미터가 있습니다.

    1. 첫 번째 파라미터는 ‘상품이름’입니다. 이는 생성된 링크의 텍스트로 표시됩니다.
    2. 두 번째 파라미터는 ‘쿠팡에서 제공하는 원래코드’입니다. 이는 생성된 링크의 실제 URL입니다.
    3. 세 번째 파라미터는 ‘새창열기 여부’입니다. 이는 링크를 클릭했을 때 새 창으로 열지 여부를 결정합니다. _self를 입력하면 현재 창에서 열리고, 파라미터를 전혀 입력하지 않으면 기본적으로 새 창에서 열립니다.
    4. 경제활동 이해관계 문구는 자동으로 아랫부분에 나오도록 하였습니다.

    예를 들어, 다음과 같은 문장을 사용하여

    (※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.).

    함수를 호출할 수 있습니다:

    [쿠팡]내블로그에보여줄상품이름,쿠팡블로그용태그[/쿠팡]
    
    [쿠팡]NAS DS220+,<a href="https://link.coupang.com/a/3mFfj" target="_blank" referrerpolicy="unsafe-url"><img src="https://image10.coupangcdn.com/image/affiliate/banner/78b5256c719eff510548dc7cfb6d4f3a@2x.jpg" alt="시놀로지 디스크 스테이션 NAS DS220+" width="120" height="240"></a>[/쿠팡]
    
    

    위 문장에서 ‘상품이름’은 “NAS DS220+”이고, ‘쿠팡에서 제공하는 원래코드’는 “https://link.coupang.com/a/3mFfj”입니다. ‘새창열기 여부’는 “_self”로 설정되어 있습니다.

    실제로 이 코드를 블로그에 포스팅하면 아래와 같이 링크가 생성됩니다:


    (※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.).


    이렇게 생성된 링크를 클릭하면 “NAS DS220+”라는 텍스트를 가진 링크가 열리며, 클릭 시 새 창이 열리거나 3번째 파라미터값을 입력했다면 그 입력된 결과대로 창이 열리거나 그대로 연결될 것입니다.

    위의 스니핏 코드가 필요하신 분들은 요청해주시기 바랍니다.

    이와 같이 [쿠팡][/쿠팡] 함수를 사용하여 상품 링크를 생성할 수 있습니다. 

    파라미터를 조정하여 원하는 링크 형식을 만들어보세요.

  • VM 자동화 시스템 구축 할때 윈도우 배치 스크립트

    VM 자동화 시스템 구축 할때 윈도우 배치 스크립트

    각 VM마다 컨트롤 하기 위해서는 VM안에서 쉽게 관리자 프로그램을 설치 할 수 있어야 합니다.

    팀뷰어 원격 시스템으로 되어져있더라도 VM갯수가 100개이상 되거나 혹은 1000개 이상이 될 경우 각각 한개씩 설정한다는 시간소비와 노력소비가 많이 들어갑니다. 그로인해서 이를 쉽고 빠르고 한번에 관리자에서 할 수 있도록 기본 파일을 설치 해 놓아야 합니다.

    그 중 한가지가 리눅스에서 많이 사용하고 있는 wget 이러한 기능을 사용할 수 있는 프로그램입니다.

    wget.exe 파일을 윈도우 폴더 어디서든 사용할 수 있도록 환경변수를 지정해놓고 원하는 자동화 툴을 다운로드 받아 바로 실행 해야 합니다.

    오늘은 wget.exe 파일을 자동으로 업데이트 할 수 있도록 VM 자동화 시스템 구축 기본 베이스를 만들어 보겠습니다.

    자동화 시스템 구축

    1. 자동화 업데이트 가능한 스크립트를 제작합니다.

    우선 자동화 업데이트를 위한 wget.exe 파일이 자동으로 다운받고 자동으로 업데이트 되도록 설치합니다.

    아래 스크립트를 이용하여 CMD 화면에서 동작 시킬 수 있습니다.

    copy con updateWget.bat
    
    echo off
    
    set FORDER_WGET=%HOMEDRIVE%\_자료실\티온\WGET
    set FILEDOWNLOAD_WGET=https://vlog.tion.co.kr/app/wget.exe
    set SHORT_LINK=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\updateWget - 바로 가기.lnk
    
    mkdir "%HOMEDRIVE%\_자료실".
    mkdir "%HOMEDRIVE%\_자료실\티온".
    mkdir %FORDER_WGET%
    
    
    IF EXIST "%HOMEDRIVE%\_자료실\티온\WGET\wget.exe" (
    	del "%HOMEDRIVE%\_자료실\티온\WGET\wget.exe"
    ) 
    
    IF NOT EXIST "%HOMEDRIVE%\_자료실\티온\updateWget.bat" (
    
    	copy updateWget.bat "%HOMEDRIVE%\_자료실\티온".
    )
    
    
    cd %FORDER_WGET%
    
    if exist "%SHORT_LINK%" (
    	ECHO "EXIST shortcut"
    	GOTO COMMON
    ) else (
    	ECHO "Making shortcut"
    	GOTO SHORTCUT
    	 
    )
    
    :SHORTCUT
    powershell -Command "$ws =  New-Object -ComObject ('WScript.Shell'); $s = $ws.CreateShortcut('%SHORT_LINK%'); $s.TargetPath = 'C:\_자료실\티온\updateWget.bat'; $s.Save()"
    
    GOTO COMMON
    
    
    :COMMON
    IF EXIST "%HOMEDRIVE%\Windows\System32\wget.exe". (
    
    	wget %FILEDOWNLOAD_WGET%
    
    	del "%HOMEDRIVE%\Windows\System32\wget.exe".
    	copy %FORDER_WGET%\wget.exe. "%HOMEDRIVE%\Windows\System32".
    
    ) ELSE (
    	powershell "(New-Object System.Net.WebClient).DownloadFile('%FILEDOWNLOAD_WGET%','%HOMEDRIVE%\Windows\System32\wget.exe')"
    	copy "%HOMEDRIVE%\Windows\System32\wget.exe". %FORDER_WGET%
    )
    
    
    
    
    #Ctrl + Z 눌러서 저장합니다. 

    Ctrl +Z 눌러야지만 파일이 저장됩니다.

    만들어진 파일을 실행 해 봅니다.

    2. wget.exe 파일이 동작하는지 확인 합니다.

    파일이 정상적으로 동작을 했다면 wget.exe 파일이 실행되는것을 확인 할 수 있습니다.

    정상적으로 스크립트가 실행되었으며 파일도 잘 복사 되었습니다.

    이제 wget.exe 라고 명령어를 입력하면 바로 사용 할 수 있습니다.

    3. 윈도우 시작 프로그램에 등록합니다.

    레지스트 등록방법도 존재하지만 우리는 쉽고 빠르게 할 수 있는 방법인 숏컷 바로가기를 만들겠습니다.

    만들어진 배치파일을 그냥 이동시키거나 복사해도 되며 제가 한것처럼 바로가기를 만들어서 넣어도 됩니다.

    윈도우키+ R 버튼을 눌러서 shell:startup 이라고 입력합니다.

    아래처럼 윈도우 시작프로그램 폴더가 열립니다.

    그 폴더로 방금 만든 배치파일을 그냥 옮기셔도 됩니다. 복사하셔도 되고요.

    저는 위에서 말씀드린것처럼 배치파일에 오른쪽마우스로 꾹 눌러서 드래그 한다음 시작프로그램 폴더에서 손을 떼면
    [ 여기에 바로가기 만들기 ] 항목을 클릭 할 수 있습니다.

    이제부터 VM 게스트 PC를 재부팅 할 때마다 자동으로 wget.exe 새로운 버전으로 다운받고 업데이트를 진행하게 됩니다.

    최종적으로 CMD창을 열어서 wget 명령이 동작하는지 확인합니다.

    정상적으로 되었네요.

    자동화 시스템 구축 이제부터 원하는 관리자 파일을 내가 원하는 폴더에 설치하고 업데이트를 할 수 있게 되었습니다.

    기초 부분이 끝났습니다.

    이제 모든 VM 마다 이렇게 설치해서 자동화를 만들 수 있습니다.

    이렇게 만들어진 자동화 시스템 구축은 팀뷰어 같은 원격 프로그램도 필요가 없으며 오직 게스트 PC만 많으면 됩니다.

    새로운 VM에 적용해보니 바로 wget 명령어가 동작하는것을 확인하였습니다.

    저처럼 자신만의 자동화 시스템을 구축하고 있다면 이 방법은 여러분들에게 많은 도움이 되는 기초 단계의 강좌가 될겁니다.

    감사합니다.

  • c# Base64 Decoding from php encoding AND HMAC SHA256

    c# Base64 Decoding from php encoding AND HMAC SHA256

    PHP에서 Base64 인코딩 하고 C#에서 디코딩

    첫번째는 단순히 Base64 인코딩을 C#에서 디코딩하는 코드

    두번째는 hash_hmac(‘sha256’) 함수를 이용하여 PHP에서 인코딩하고 C#에서 디코딩 하는 코드

    Just Base 64 Encoding

    PHP Code

    $phpEncodingString = "AAAAAA" . "|" . "BBBBBB";
    echo base64_encode($phpEncodingString );
    
    //output -> QUFBQUFBfEJCQkJCQg==

    C# Code

    string fromPHPencodingString = "QUFBQUFBfEJCQkJCQg==";
    byte[] byte64 = Convert.FromBase64String(fromPHPencodingString);
    string decodingString = Encoding.UTF8.GetString(byte64);
    Console.WriteLine("Result: {0}", decodingString);
    
    //output -> Result: AAAAAA|BBBBBB

    Base 64 Encoding with hash_hmac(‘sha256’)

    PHP Code

    $key = "AAAAA";
    $message = "BBBBB";
    
    $hashString = hash_hmac('sha256', $message, $key);
    echo base64_encode(strtoupper($hashString ));
    
    //output -> NjZDNTc2NTBCODhBMzcyNTFDMjgzNzA1QkUwNUJEOEI0MDNDMUU3QzMwMjEzRkQ1MkIwNjI3QTJFMjAzQjY2RA==

    C# Code

    string key = "AAAAA";
    string messeage = "BBBBB";
    
    var keyByte = encoding.GetBytes(key);
    using (var hmacsha256 = new HMACSHA256(keyByte))
    {
    	hmacsha256.ComputeHash(encoding.GetBytes(message));
    
    	MessageBox.Show(ByteToString(hmacsha256.Hash));
    
    	string fromPHPencodingString = ByteToString(hmacsha256.Hash);
    	byte[] basebyte = System.Text.Encoding.UTF8.GetBytes(fromPHPencodingString);
    	string base64String = Convert.ToBase64String(basebyte);
    	MessageBox.Show(String.Format("Result: {0}", base64String));
    }
      
    
    static string ByteToString(byte[] buff)
    {
    	string sbinary = "";
    	for (int i = 0; i < buff.Length; i++)
    		sbinary += buff[i].ToString("X2"); /* hex format */
    	return sbinary;
    }
    
    //output -> NjZDNTc2NTBCODhBMzcyNTFDMjgzNzA1QkUwNUJEOEI0MDNDMUU3QzMwMjEzRkQ1MkIwNjI3QTJFMjAzQjY2RA==

    단순 Base64 인코딩은 디코딩 할 경우 문자가 그대로 복원이 되지만 hash_hmac(‘sha256’) 함수를 이용할 경우 원래의 문자열 복구 불가능하므로 인코딩 된 결과물을 바탕으로 비교하여 True / False 구분해야합니다.

  • php 특정 날짜 남은 날짜 계산

    php 특정 날짜 남은 날짜 계산

    특정 날짜에서 남은 날짜를 계산해야하는 경우는 이렇습니다.

    회원 가입일로 부터 365일 후에 재 가입을 할 수 있어야 하므로 완료 날짜 혹은 남은 날짜를 매일 체크해야합니다.

    회원관리 시스템에서 특정 날짜 기준으로 남은 날짜 계산 하는 알고리즘 입니다.

    PHP 언어를 사용할 때 그대로 복사 붙여넣기 해서 사용하면 됩니다,

    
    #2017년 7월 21일부터 오늘까지 일수를 알아내어 남은 기간 $period = 9999일에서 빼주면 회원 남은 기간
    	
    $day_start = date("Y-m-d", strtotime("20170721"));
    
    $day_today = date("Y-m-d", time());
    
    $remainDays = (int)($period - ( strtotime($day_today) - strtotime($day_start) ) / 86400);
    
    echo sprintf('%s__%s__%s__%s__%s', strtotime($day_today), strtotime($day_start), $remainDays, $day_today, $period);
    
    
    

    이 알고리즘을 이용하여 회원 남은 기간동안 프로그램을 제공해줄 수 있습니다.

    86400 으로 나눠주는 이유는 하루가 86400초 이기때문입니다.

    60초 * 60분 * 24시간 = 86400 초

    *strtotime 으로 문자날짜를 time 수치로 변경할 경우 초단위로 환산됩니다.