import requests
from bs4 import BeautifulSoup

response = requests.post(tranUrl, headers=headers, data=data, verify=False)
soup = BeautifulSoup(response.content,"html.parser")
print(soup.find(id="tw-answ-target-text").text)
return soup.find(id="tw-answ-target-text").text

verify=False 설정으로 SSL오류를 해결하고 나면 이번에는 아래와 같은 경고가  표시됩니다.

InsecureRequestWarning: Unverified HTTPS request is being made to host 'www.google.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(

인증서 검증으로 하라는 경고인데 아래와 같이 작성하며 경고를 숨길 수 있습니다.

import requests
from bs4 import BeautifulSoup
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)          # InsecureRequestWarning 경고를 무시하도록 설정

response = requests.post(tranUrl, headers=headers, data=data, verify=False)
soup = BeautifulSoup(response.content,"html.parser")
print(soup.find(id="tw-answ-target-text").text)
return soup.find(id="tw-answ-target-text").text

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)          # InsecureRequestWarning 경고를 무시하도록 설정

위 2개 코드를 추가하게 되면 해결됩니다.

◊  회사에서 Python / Request 를 사용하여 데이터 수집 프로그램을 만들다 보면 request 모듈 호출시 아래와 같은 오류를 만나게 됩니다. 그에 따른 오류 해결 방법 입니다.

url = "이런 저런 URL"
response = requests.post(url, headers=headers, data=data)
soup = BeautifulSoup(response.content,"html.parser")
print(soup.find(id="tw-answ-target-text").text)

 

◊ 오류 메시지

SSLError: HTTPSConnectionPool(host='www.google.com', port=443): Max retries exceeded with url: /async/translate?vet=eiv=1&yv=3&cs=1&_fmt=pc (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1133)')))

 

◊ 조치 방법

# verify=False 옵션을 지정해주면 SSL오류가 발생하지 않음
response = requests.post(url, headers=headers, data=data, verify=False)
soup = BeautifulSoup(response.content,"html.parser")
print(soup.find(id="tw-answ-target-text").text)

개발업무 특성상 general log를 검색할 일이 자주 발생합니다.

적은양이 아니기에 notepad를 통해서는 검색이 제한적이기에

python을 활용해 특정 단어가 포함된 쿼리만을 추출해 보았습니다.

import os
import chardet
import pandas as pd
import numpy as np
from queue import Queue
from datetime import datetime

"""
입력된 값이 날짜형 값인지 검사
"""
def f_isDateTimeCheck(_inWord):
    try:
        dt_date = datetime.strptime(_inWord, '%Y-%m-%d')
    except Exception as ex:
        # print(ex)  # 여기 오류는 날짜 형식을 검증하기위한 부분이라 오류 로그를 찍으면 안됨
        return False 
    return True

"""
입려된 단어들이 본 Line에 모두 포함되는지 여부
"""
def f_QuerToStringAndFind(_line_queue, _findWordList):
    lineStr = ""
    findCnt = 0
    # 하나의 문자열로 결합
    while _line_queue.qsize() > 0:
        lineStr = lineStr + _line_queue.get()
    for str in _findWordList:   # 검색어 목록
        if str in lineStr:
            findCnt = findCnt + 1
    
    # print(findCnt, len(_findWordList), findCnt != len(_findWordList), lineStr)
    if findCnt != len(_findWordList):
        return "" 
    return lineStr

searchWordsList = ['Execute', '34356', 'like'] # 하나의 로그에 모두 포함되어 있어야 하는 검색어 목록
_line_queue = Queue()
_line_number_queue = Queue()

file_path = r'd:\generallog\20240611_generallog.log'
# 검색한 내용을 기록할 파일 생성
new_file_name = "%s/FindGeneralLog_%s.SQL" % (os.path.dirname(file_path), datetime.now().strftime('%Y%m%d%H%M%S'))
find_word_new_file = open(new_file_name, "w")

try:
	# 하나의 컬럼으로 만들어 주기위해 열구분자(sep)를 임이로 설정하였습니다.
    df_log = pd.read_table(file_path, sep='✱%*', encoding='UTF-8', encoding_errors='ignore', header=None, engine='python')
    query_cnt = 1
    for row in df_log.itertuples():
        try:
            _line_original = str(row[1])
            _line_original = _line_original.strip()     # 원본 내용, 앞뒤공백 삭제
            if len(_line_original) == 0:
                continue     # 공백행 무시
            
            # 라인의 앞 10자리가 날짜 형식이면 로그의 시작
            if f_isDateTimeCheck(_line_original[0:10]):
                _result = f_QuerToStringAndFind(_line_queue, searchWordsList)
                if len(_result) > 3:
                    findTab = _result.find("\t")
                    dt = datetime.fromisoformat(_result[0:findTab])
                    formatted_time_str = dt.strftime("%Y-%m-%d %H:%M:%S") + f".{int(dt.microsecond):05d}"   # 밀리초까지 기록
                    find_word_new_file.write("%s %s \n" % (formatted_time_str, _result[findTab:].replace("\n", " ")) )   # 찾은 Line에서 쿼리만 추출하여 파일에 기록
                    
            _line_queue.put(_line_original + '\n')
            _line_number_queue.put(row[0])
        except Exception as ex:
            print(ex)
            continue
except Exception as ex:
    print(ex)

find_word_new_file.close()
print("검색 작업이 완료되었습니다.")

 

[JST] SXH-001T-P0.6 핀을 압착할 수 있음

 

☑ 수백개의 폴더를 생성하고 생성된 모든 폴더에 동일하게 2~3개의 파일을 복사해야할 업무가 발생하여

Jmeter를 이용하여 처리해 보았습니다. 

  개요

  요소 위치

   설정

 

위에서 생성한 폴더의 하위에서 아래 Copy 작업이 발생하게 됩니다.

최종적으로 우측의 명령이 실행 됩니다. Executing: cmd /C mkdir 127.0.0.1

 

최종적으로 우측의 명령이 실행 됩니다. Executing: cmd /C copy d:\file\*.* 127.0.0.1

 

CSV파일에는 220개이 IP 정보가 저장되어 있고, Column Header는 없습니다.

 

✅ Jmeter를 이용하면 다양한 업무를 쉽고 빠르게 처리할 수 있으니 고민해 보시길 바랍니다.

개인 프로젝트 or 진행해야할 일들 or 각종 기록을 Redmine으로 관리하고 있습니다.

그러다 보니 본문 수정이 작고 가끔은 본문과는 별도로 덧글에도 정보를 기록하게 되는데요

이력과 덧글이 섞여 있으면 보기가 불편해서 아래와 같은 수정 이력 정보를 저거하려 합니다.

Redmine DB에 sp를 만들어 주신 후 사용하시면 됩니다. 아래 코드는 2달 지낸 이력을 삭제하게 됩니다.

use `redmine_default`;

DROP PROCEDURE IF EXISTS `sp_journals_cleanup`;
DELIMITER $$
CREATE PROCEDURE `sp_journals_cleanup`(
		OUT o_result	int
)
DETERMINISTIC
BEGIN
    /*
        레드마인에서 2달 이상 지난 수정이력은 제거
     */
    set @v_delete_date := date_add(current_timestamp, interval -2 month);   -- 동일한 날짜를 기준으로 제거하기 위한 삭제 기준일
    set o_result = 0;

    delete ta
    from journal_details as ta
    inner join (    select id
                    from journals
                    where journalized_type = 'issue' and notes = '' and created_on < @v_delete_date
    ) as tb on ta.journal_id = tb.id;
    set o_result = o_result + row_count();

    delete from journals
    where journalized_type = 'issue' and notes = '' and created_on < @v_delete_date;

    set o_result = o_result + row_count();

END $$
DELIMITER ;

+ Recent posts