이상한 MYPI

이상한
접속 : 6450   Lv. 110

Category

Profile

Counter

  • 오늘 : 377 명
  • 전체 : 8001768 명
  • Mypi Ver. 0.3.1 β
[공부 - PG] 가격 변동 확인용 프로그램 수정 (1) 2021/05/23 PM 08:49

지난 주에 만들었던게 너무 대충 만들어서 조금만 덜 대충 만들었습니다..


프로그램이라고 오버해서 말하지만 어차피 파이선 스크립트



 

수정점

1. 메일서버 정보를 sqlite로 옮김

1. xpath등 파싱할 데이터를 sqlite로 옮겨서 가능한 범용적 처리 가능하게 함


이 이상 손 될거는 없어보이네요..

 

문제점은

1. 역시 예외 처리는 1도 없음

1. 서버 정보 소스에는 안넣었어도 sqlite의 보안처리가 없기 때문에 보안에는 큰 의미 없음..


이번 수정때문에 소스는 수정없이 넣어도 되겠네요..


우선 DB 바뀐거


SITE

파싱할 데이터를 집어 넣을 칼럼추가

01.png

 

 ITEM

URL생성용 OPT의 필드명 좀 수정

OPT3 타입 잘 못지정한거 수정함

02.png

 

 메일 정보용 테이블

뭐 그냥 보면 무슨 뜻일지 알듯

03.png

 

 

추가 항목은 이런식으로 넣음

04.png

 

 


소스

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

import smtplib, ssl
import email.utils
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import sqlite3

#import logging
#logging.basicConfig(level=logging.DEBUG, filename="test.log", format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')

options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
chrome_prefs = {}
options.experimental_options["prefs"] = chrome_prefs
chrome_prefs["profile.default_content_settings"] = {"images": 2}
chrome_prefs["profile.managed_default_content_settings"] = {"images": 2}
driver = webdriver.Chrome(executable_path="/usr/lib/chromium-browser/chromedriver", chrome_options=options)

dbPath = "./"
dbFileName = "PriceChk.sqlite3"
conn = sqlite3.connect(dbPath + dbFileName)

cur = conn.cursor()

SELECT_TEXT = "select B.ITEM_ID, B.NAME, A.SITE_TYPE, A.URL, A.URL_TYPE, B.URL_OPT1, B.URL_OPT2, B.URL_OPT3, "
SELECT_TEXT += "A.OBJ_TYPE_ONLYONE, A.OBJ_TYPE_ATTRIBUTE, A.OBJ_XPATH, A.OBJ_ATTRIBUTE, A.OBJ_TEXT_START, A.OBJ_TEXT_END "
SELECT_TEXT += "from SITE A, ITEM B where B.DEL=0 AND A.SITE_TYPE=B.SITE_TYPE"

dataList = cur.execute(SELECT_TEXT).fetchall()
for data in dataList:
    dataItemID = data[0]
    dataName = data[1]
    dataSiteType = data[2]
    dataUrl = data[3]
    dataUrlType = data[4]
    dataUrlOpt1 = data[5]
    dataUrlOpt2 = data[6] or ""
    dataUrlOpt3 = data[7] or ""

    dataObjTypeOnlyOne = data[8]
    dataObjTypeAttribute = data[9]
    dataObjXpath = data[10]
    dataObjAttribute = data[11]
    dataTextStart = data[12] or ""
    dataTextEnd = data[13] or ""
    
    url = ""
    if dataUrlType == 1:
        url = dataUrl.format(dataUrlOpt1)
    elif dataUrlType == 2:
        url = dataUrl.format(dataUrlOpt1, dataUrlOpt2)
    elif dataUrlType == 3:
        url = dataUrl.format(dataUrlOpt1, dataUrlOpt2, dataUrlOpt3)

    #print(url)
    driver.get(url)
    
    newPrice = ""
    if dataObjTypeOnlyOne == 1:
        targetObj = driver.find_element_by_xpath(dataObjXpath)
        tempPrice = ""
        if dataObjTypeAttribute == 1:
            tempPrice = targetObj.get_attribute(dataObjAttribute)
        else:
            tempPrice = targetObj.text
        newPrice = tempPrice[len(dataTextStart):len(tempPrice)-len(dataTextEnd)]
    else:
        for targetObj in driver.find_elements_by_xpath(dataObjXpath):
            tempPrice = ""
            if dataObjTypeAttribute == 1:
                tempPrice = targetObj.get_attribute(dataObjAttribute)
            else:
                tempPrice = targetObj.text
            if tempPrice.startswith(dataTextStart) and tempPrice.endswith(dataTextEnd):
                newPrice = tempPrice[len(dataTextStart):len(tempPrice)-len(dataTextEnd)]
                break
    
    print("{0}:{1}:{2}".format(dataItemID, dataName, newPrice))

    oldPriceSelect = cur.execute("select ITEM_ID, PRICE, DATE from DATA where ITEM_ID = ? order by DATE desc limit 1", (str(dataItemID),)).fetchone()
    oldPrice = ""
    if not oldPriceSelect is None:
        oldPrice = oldPriceSelect[1]

    if oldPrice != newPrice:
        cur.execute("insert into DATA ( ITEM_ID, PRICE, DATE ) VALUES (?, ?, datetime('now', 'localtime'))", (dataItemID, newPrice))

        mailInfo = cur.execute("select SMTP_URL, SMTP_PORT, SEND_MAIL_ADDRESS, SEND_MAIL_PASSWORD, RECEIVE_MAIL_ADDRESS from MAILINFO").fetchone()
        if mailInfo != None:
            fromaddr = mailInfo[2]
            toaddr = mailInfo[4]
            
            msgBody = "{0}의 가격 변경\n{1}→{2}\n{3}".format(dataName, oldPrice, newPrice, url)
            msg = MIMEMultipart()
            msg['From'] = email.utils.formataddr(('가격봇', fromaddr))
            msg['To'] = email.utils.formataddr(('너님', toaddr))
            msg['Subject'] = "{0}의 가격 변경".format(dataName)
            msg.attach(MIMEText(msgBody))

            id = fromaddr
            password = mailInfo[3]

            context = ssl.create_default_context()
            with smtplib.SMTP(mailInfo[0], mailInfo[1]) as server:
                server.ehlo()  # Can be omitted
                server.starttls(context=context)
                server.ehlo()  # Can be omitted
                server.login(id, password)
                server.sendmail(fromaddr, toaddr, msg.as_string())

conn.commit()
conn.close()
driver.close()
driver.quit()

 

소스 수정으로 이제 그냥 붙일 수 있네요...


뭐.. 어차피 자기 보존용이지만;;;;;

신고

 

물의보호막    친구신청

그래도 이런거 오픈해주시는 정성이 좋군용
X