언유상씨의 건전한 취미생활

파이썬 웹크롤링을 사용한 날씨 정보 프로그램 - 2 (GUI, 메일전송까지) 본문

건전한 학습생활 - python

파이썬 웹크롤링을 사용한 날씨 정보 프로그램 - 2 (GUI, 메일전송까지)

언유상 2019. 11. 23. 13:13

1) 소스코드

(*** 처리된 부분은 아이디, 비밀번호나 파일의 경로 등으로, 개인정보 보호를 위해 가린다.)

1. 이메일 주소를 입력 받고, 웹 크롤링으로 날씨 정보를 받은 뒤 받은 메일 주소로 메일 발송

동시에 메일 주소는 txt파일에 저장된다.

 

코드가 조금 지저분해도 양해 부탁드립니다...!

소스코드 설명은 다음에 계속됩니다!

 

import sys

import requests

import smtplib

from PyQt5.QtWidgets import QApplication, QMessageBox, QMainWindow, QWidget, QLineEdit, QPushButton, QLabel, QTextBrowser, QGridLayout, QDesktopWidget

from PyQt5.QtGui import QIcon

from PyQt5.QtCore import QDateTime, Qt

from bs4 import BeautifulSoup

from email.mime.text import MIMEText

from urllib.request import urlopen

 

class MyApp(QMainWindow):

 

    def __init__(self):

        super().__init__()

       

        self.setWindowIcon(QIcon('MTC.png')) #아이콘 집어넣기

     

        self.setWindowTitle('MTCSUP')

        self.setGeometry(100, 100, 450, 400)

        self.center() #중앙으로 오게

       

        self.table_widget = MyWidget(self) #새로운 클래스에서 정보 가져오기

        self.setCentralWidget(self.table_widget)

       

        self.datetime = QDateTime.currentDateTime() #현재의 시간을 반환

        self.Timenotice()

       

        self.show()

   

    def center(self): #중앙으로 오게 설정

 

        qr = self.frameGeometry()

        cp = QDesktopWidget().availableGeometry().center()

        qr.moveCenter(cp)

        self.move(qr.topLeft())

   

    def Timenotice(self):

       

        self.statusBar().showMessage(self.datetime.toString('yy.M.d hh:mm'))

        self.show

       

    def closeEvent(self, event): #종료시 되물음

 

        reply = QMessageBox.question(self, '알림','종료하시겠습니까?',

                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

 

        if reply == QMessageBox.Yes:

            event.accept()

        else:

            event.ignore()

 

class MyWidget(QWidget):

   

    def __init__(self,MyApp):

        super(QWidget,self).__init__(MyApp)

       

        self.initUI()

       

    def initUI(self):

        # 이메일 주소 입력 crawl_news 메소드 호출

        self.le = QLineEdit()

        self.le.setPlaceholderText('이메일주소')

        self.le.returnPressed.connect(self.crawl_weather)

 

        self.btn = QPushButton('Send')

        self.btn.clicked.connect(self.crawl_weather)

 

        self.lbl = QLabel('이메일 주소를 입력하시오.')

 

        self.tb = QTextBrowser()

        self.tb.setAcceptRichText(True)

        self.tb.setOpenExternalLinks(True) #외부링크 허용

 

        grid = QGridLayout()

        grid.addWidget(self.le, 0, 0, 1, 3)

        grid.addWidget(self.btn, 0, 3, 1, 1)

        grid.addWidget(self.lbl, 1, 0, 1, 4)

        grid.addWidget(self.tb, 2, 0, 1, 4)

 

        self.setLayout(grid)

        self.tb.append(self.crawl_weather())

        self.show()

 

 

       

    def crawl_weather(self): #날씨 크롤러 작동

        add = self.le.text()

        def weather_N():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107") 

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('div > em')) 

            weather_a = str(a) 

            weather_a_s = weather_a.split('\t')

            list_a = list(weather_a_s)

            weather_point = list_a[7]

            str_weather = str(weather_point)

            weather_point_s = weather_point.split('<')

            Now = weather_point_s[0]

            weather_Now = float(Now)

            return weather_Now

 

        def condition_N():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107")

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('div > em'))

            weather_a = str(a) 

            weather_a_s = weather_a.split('\t')

            list_a = list(weather_a_s)

            weather_point = list_a[7]

            str_weather = str(weather_point)

            weather_point_s = weather_point.split('<')

            weather_sit = weather_point_s[3]

            str_weather_1 = str(weather_sit)

            weather_sit_s = str_weather_1.split('>')

            Con = weather_sit_s[1]

            weather_Con = str(Con)

            return weather_Con

 

        def weather_n_max():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107")    

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('ul > li.nm > span')) 

            weather_N_a = str(a)

            weather_N_S = weather_N_a.split('>')

            weather_N_S_a = str(weather_N_S)

            weather_N_max = weather_N_S[3]

            weather_N_max_s = str(weather_N_max)

            weather_N_max_1 = weather_N_max_s.split('<')

            weather_max = weather_N_max_1[0]

            to_max= float(weather_max)

            return to_max

 

        def weather_n_min():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107") 

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('ul > li.nm > span')) 

            weather_N_a = str(a)

            weather_N_S = weather_N_a.split('>')

            weather_N_S_a = str(weather_N_S)

            weather_N_min = weather_N_S[1]

            weather_N_min_s = str(weather_N_min)

            weather_N_min_1 = weather_N_min_s.split('<')

            weather_min = weather_N_min_1[0]

            to_min = float(weather_min)

            return to_min

 

        def weather_t_max():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107")  

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('ul > li.nm > span')) 

            weather_N_a = str(a)

            weather_N_S = weather_N_a.split('>')

            weather_N_S_a = str(weather_N_S)

            weather_N_max = weather_N_S[7]

            weather_N_max_s = str(weather_N_max)

            weather_N_max_1 = weather_N_max_s.split('<')

            weather_max = weather_N_max_1[0]

            tom_max = float(weather_max)

            return tom_max

 

        def weather_t_min():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107") 

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('ul > li.nm > span')) 

            weather_N_a = str(a)

            weather_N_S = weather_N_a.split('>')

            weather_N_S_a = str(weather_N_S)

            weather_N_min = weather_N_S[5]

            weather_N_min_s = str(weather_N_min)

            weather_N_min_1 = weather_N_min_s.split('<')

            weather_min = weather_N_min_1[0]

            tom_min = float(weather_min)

            return tom_min

 

        def weather_t_n_Con():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107")   

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('ul > li.info'))

            weather_N_a = str(a)

            weather_N_S = weather_N_a.split('>')

            weather_N_S_a = str(weather_N_S)

            weather_N_min = weather_N_S[:28]

            list_1 = []

            for i in (15, 16, 18, 19):

                aa = weather_N_min[i]

                aaa = aa.split('<')

                aaaa = aaa[0]

                list_1.append(aaaa)

            w,x,y,z = list_1

            text = ('기상상태 : %s, %s: %s%s' %(w,x,y,z))

            return text

 

        def weather_t_a_Con():

            html = urlopen("https://weather.naver.com/rgn/townWetr.nhn?naverRgnCd=02190107") 

            bsObject = BeautifulSoup(html, "html.parser")

            a = (bsObject.select('ul > li.info'))

            weather_N_a = str(a)

            weather_N_S = weather_N_a.split('>')

            weather_N_S_a = str(weather_N_S)

            weather_N_min = weather_N_S[:28]

            list_1 = []

            for i in (22, 23, 25, 26):

                aa = weather_N_min[i]

                aaa = aa.split('<')

                aaaa = aaa[0]

                list_1.append(aaaa)

            w,x,y,z = list_1

            text = ('기상상태 : %s, %s: %s%s' %(w,x,y,z))

            return text

 

        def dif_chk_a():

            dif = weather_t_max() - weather_n_max()

            if dif >= 0 :

                text = '내일 오후는 오늘보다 %0.1f℃ 높습니다.'%dif

                return text

            else:

                diff = abs(dif)

                text = '내일 오후는 오늘보다 %0.1f℃ 낮습니다.'%diff

                return text

 

        def dif_chk_n():

            dif = weather_t_min() - weather_n_min()

            if dif >= 0:

                text = '내일 오전은 오늘보다 %0.1f℃ 높고,'%dif

                return text

            else:

                diff = abs(dif)

                text = '내일 오전은 오늘보다 %0.1f℃ 낮고,'%diff

                return text

 

        def execute():

            b = '현재 기온 : %0.1f℃, %s입니다.\n내일 오전 : %0.1f℃ %s\n내일 오후 : %0.1f℃ %s \n%s \n%s\n\n.

'% (weather_N(), condition_N(),weather_t_min(),weather_t_n_Con(),weather_t_max(), weather_t_a_Con(),dif_chk_n(),dif_chk_a())

            return b

 

        def execute_notice():

            b = '현재 기온 : %0.1f℃, %s입니다.\n내일 오전 : %0.1f℃ %s\n내일 오후 : %0.1f℃ %s \n%s \n%s\n\n이메일을 입력한 뒤, Send버튼을 누르고 메일이 보내지는데 까지 시간이 조금 걸릴 수 있습니다.'% (weather_N(), condition_N(),weather_t_min(),weather_t_n_Con(),weather_t_max(), weather_t_a_Con(),dif_chk_n(),dif_chk_a())

            return b

        if add:

            self.lbl.setText('이메일이 전송되었습니다. 오늘의 날씨입니다.') #문구 변경

            f = open(r"***", 'a')

            data = "%s\n" %add

            f.write(data)

            f.close()

 

            s = smtplib.SMTP('smtp.gmail.com', 587)

            s.starttls()

            s.login('mediatechcon123@gmail.com', '***')

            msg = MIMEText('%s' %execute())

            msg['Subject'] = '미콘 서포터즈에서 날씨를 알려드립니다!'

            s.sendmail("mediatechcon123@gmail.com", "%s" %add ,msg.as_string() )

            s.quit()

        return execute_notice()

  

    

if __name__ == '__main__':

 

    app = QApplication(sys.argv)

    ex = MyApp()

    sys.exit(app.exec_())

 

2. 1에서 받은 이메일 주소를 txt파일에 저장 후, 매일 저녁 해당 이메일 주소로 메일 발송

매일 작동하는 것은, 윈도우 작업 스케줄러를 사용한다.

import smtplib

from email.mime.text import MIMEText

from urllib.request import urlopen

from bs4 import BeautifulSoup

 

f = open(r"***", 'r')

data = f.read()

a = str(data)

 

aa = a.split('\n')

aaa = len(aa)

for i in range (0,aaa,1):

    s = smtplib.SMTP('smtp.gmail.com', 587)

    s.starttls()

    s.login('mediatechcon123@gmail.com', ***')

    msg = MIMEText('aaa')

    msg['Subject'] = '미콘 서포터즈에서 날씨를 알려드립니다!'

    s.sendmail("mediatechcon123@gmail.com", "%s" %aa[i] ,msg.as_string() )

    print('성공')

    s.quit()

 

f.close()

Comments