[python應用案例] 一.BeautifulSoup爬取天氣資訊併傳送至QQ郵箱

Eastmount發表於2018-05-03

前面作者寫了很多Python系列文章,包括:

這裡寫圖片描述 這裡寫圖片描述 這裡寫圖片描述

接下來作者將學習並講解一些Python小應用,它將結合Python爬蟲、資料分析、web開發或其他功能進行介紹。一方面希望能提升讀者的Python學習興趣,另一方面也希望讀者能學到些知識,做些好玩的應用。本篇文章主要講解BeautifulSoup爬取每日天氣資訊,然後將資訊傳送至QQ郵箱,其難點是如何配置QQ郵箱傳送Python郵件。
基礎性應用文章,希望對您有所幫助,如果文章中出現錯誤或不足之處,還請海涵~


一. BeautifulSoup爬取天氣資訊

1.分析網頁

中國天氣網: http://www.weather.com.cn/weather/101260101.shtml
我們需要爬取貴陽市當天的天氣資訊,比如“5月3日 陣雨 18/15℃”


接下來通過瀏覽器審查元素,可以看到這些資訊位於<li class="sky skyid lv3 on">元素下,接著我定義class為“wea”和“tem”的元素進行定位,核心程式碼為:
name = soup.find_all(attrs={"class":"sky skyid lv3 on"})



2.完整程式碼

# -*- coding: UTF-8 -*-
import urllib
import urllib.request
from bs4 import BeautifulSoup

#下載資料
url = "http://www.weather.com.cn/weather/101260101.shtml"
content = urllib.request.urlopen(url).read()
soup = BeautifulSoup(content,"html.parser")
#print(soup.title.get_text())

content = ""
name = soup.find_all(attrs={"class":"sky skyid lv3 on"})
for u in name:
    wea = u.find(attrs={"class":"wea"}).get_text()
    tem = u.find(attrs={"class":"tem"}).get_text()
    content = "天氣:" + wea + " 溫度:" + tem
    content = content.replace("\n","")
    print(content)

輸出結果如下圖所示:




二. QQ郵箱設定STMP

在使用Python自動傳送郵件之前,需要對我們的QQ郵箱進行簡單的配置,過程如下:

1.首先登陸QQ郵箱,選擇“賬戶”如下圖所示:



2.在賬戶頁面往下拉,看到“POP3/SMTP”設定,點選開啟按鈕,如下圖所示:



3.彈出如下圖所示介面,然後傳送這條簡訊至指定號碼,點選“我已傳送”按鈕。



4.彈出的提示中會顯示16位授權碼,注意一定要記住這個授權碼,後面寫Python程式碼也需要,然後點選“確定”按鈕。



5.接下來將收取選項設定為“全部”,並點選“儲存”按鈕即可。注意埠號如下:




三. Python自動傳送郵件

Python 的 email 模組裡包含了許多實用的郵件格式設定函式,可以用來建立郵件“包裹”。使用的 MIMEText 物件,為底層的 MIME(Multipurpose Internet MailExtensions,多用途網際網路郵件擴充套件型別)協議傳輸建立了一封空郵件,最後通過高層的SMTP 協議傳送出去。 MIMEText 物件 msg 包括收發郵箱地址、郵件正文和主題,Python 通過它就可以建立一封格式正確的郵件。smtplib 模組用來設定伺服器連線的相關資訊。

Python SMTP 物件使用 sendmail 方法傳送郵件,語法如下:(參考: Python SMTP傳送郵件

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])

引數說明:

  • from_addr: 郵件傳送者地址。
  • to_addrs: 字串列表,郵件傳送地址。
  • msg: 傳送訊息

這裡要注意一下第三個引數,msg 是字串,表示郵件。我們知道郵件一般由標題,發信人,收件人,郵件內容,附件等構成,傳送郵件的時候,要注意 msg 的格式。這個格式就是 smtp 協議中定義的格式。


程式碼如下:
# -*- coding: UTF-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.header import Header

#傳送郵件
msg_from = "1455136241@qq.com"
#授權碼(而不是密碼)
EMAIL_HOST_PASSWORD = '****htacisgv****'
#接受郵件
msg_to = "15201615157@163.com"
#主題
subject = "Python測試程式碼"
#正文
content = "女神,這是我使用python smtplib及email模組傳送的郵件。"
print(content)

#MIMEText構建物件 引數分別是:郵件正文、MIMEsubtype中'plain'表示純文字、utf-8編碼
msg = MIMEText(content, 'plain', 'utf-8')
msg['Subject'] = subject
msg['From'] = msg_from
msg['To'] = msg_to

#郵件伺服器及埠號
#smtplib.SMTPServerDisconnected: Connection unexpectedly closed
try:
    s = smtplib.SMTP_SSL("smtp.qq.com",465) #埠號
    s.set_debuglevel(1)
    s.login(msg_from, EMAIL_HOST_PASSWORD)
    s.sendmail(msg_from, msg_to, msg.as_string())
    print("傳送成功")
except s.SMTPException.e:
    print("傳送失敗")
    print(e)
finally:
    s.quit()

傳送成功之後如下圖所示,注意login()輸入郵箱名和授權碼,而不是密碼。


執行過程輸出內容如下:

>>> 
女神,這是我使用python smtplib及email模組傳送的郵件。
send: 'ehlo [192.168.0.101]\r\n'
reply: b'250-smtp.qq.com\r\n'
reply: b'250-PIPELINING\r\n'
reply: retcode (250); Msg: b'smtp.qq.com\nPIPELINING\'
send: 'AUTH PLAIN ADE0NTUxMzYyNDFAcXEuY29tAGVveXFodGFjaXNndmlmYmg=\r\n'
reply: b'235 Authentication successful\r\n'
reply: retcode (235); Msg: b'Authentication successful'
send: 'mail FROM:<1455136241@qq.com> size=296\r\n'
reply: b'250 Ok\r\n'
reply: retcode (250); Msg: b'Ok'
send: 'rcpt TO:<15201615157@163.com>\r\n'
reply: b'250 Ok\r\n'
reply: retcode (250); Msg: b'Ok'
send: 'data\r\n'
reply: b'354 End data with <CR><LF>.<CR><LF>\r\n'
reply: retcode (354); Msg: b'End data with <CR><LF>.<CR><LF>'
data: (354, b'End data with <CR><LF>.<CR><LF>')
send: b'Content-Type: text/plain; charset="utf-8"\r\nMIME-Version: 1.0\r\n...r\nTo: 15201615157@163.com\r\n'
reply: b'250 Ok: queued as \r\n'
reply: retcode (250); Msg: b'Ok: queued as'
data: (250, b'Ok: queued as')
傳送成功
send: 'quit\r\n'
reply: b'221 Bye\r\n'
reply: retcode (221); Msg: b'Bye'
>>> 


四. 完整程式碼實現

完整程式碼如下所示:

# -*- coding: UTF-8 -*-
import urllib
import urllib.request
from bs4 import BeautifulSoup

#下載資料
url = "http://www.weather.com.cn/weather/101260101.shtml"
content = urllib.request.urlopen(url).read()
soup = BeautifulSoup(content,"html.parser")
content = ""
name = soup.find_all(attrs={"class":"sky skyid lv3 on"})
for u in name:
    wea = u.find(attrs={"class":"wea"}).get_text()
    tem = u.find(attrs={"class":"tem"}).get_text()
    content = "天氣:" + wea + " 溫度:" + tem
    content = content.replace("\n","")
    print(content)

#傳送郵件
import smtplib
from email.mime.text import MIMEText
from email.header import Header

msg_from = "1455136241@qq.com"
EMAIL_HOST_PASSWORD = '****htacisgv****'
msg_to = "15201615157@163.com"
subject = "Python爬取天氣"
other = content + "\n這是我使用python smtplib及email模組傳送的郵件。"
print(other)

msg = MIMEText(other,'plain','utf-8')
msg['Subject'] = subject
msg['From'] = msg_from
msg['To'] = msg_to

try:
    s = smtplib.SMTP_SSL("smtp.qq.com",465)
    s.set_debuglevel(1)
    s.login(msg_from, EMAIL_HOST_PASSWORD)
    s.sendmail(msg_from, msg_to, msg.as_string())
    print("傳送成功")
except s.SMTPException.e:
    print("傳送失敗")
    print(e)
finally:
    s.quit()

傳送成功之後如下圖所示:

需要注意,程式碼有時能傳送成功,有時報錯“smtplib.SMTPServerDisconnected: Connection unexpectedly closed”,網上說是設定埠465的原因,但作者已經設定了的,不知道為什麼?希望博友幫忙。

 (By:Eastmount 2018-5-3 下午4點   http://blog.csdn.net/eastmount/


相關文章