實習間的需求,內容是寫一支爬公開資訊觀測站重大訊息的腳本,並且將一段時間內的資訊統整,透過寫信通知給指定人,完成這部分後,再上雲然後做排程去跑,本次內容還未講述到排程部分,不過預計是使用Azure Function,以Serverless的方式,再設定Timer,固定時間去跑這隻腳本。
先了解form傳遞資料的方式 是將填入的參數丟body然後post出去
(Request URL:https://mops.twse.com.tw/mops/web/ajax_t51sb10)
Form Data參數部分
用POSTMAN嘗試與瀏覽器時一模一樣的行為 發現沒什麼問題
主要只有中文需要從字符轉換為UTF-8編碼
(e.g. 不動產->%E4%B8%8D%E5%8B%95%E7%94%A2)
接著就開始用python寫requests
import requests
from bs4 import BeautifulSoup as bsdef getInfo():
url = "https://mops.twse.com.tw/mops/web/ajax_t51sb10"
data="encodeURIComponent=1&step=1&firstin=true&id=&key=&TYPEK=&Stp=4&go=false&co_id=&r1=1&KIND=C&CODE=&keyWord=%E4%B8%8D%E5%8B%95%E7%94%A2&Condition2=2&keyWord2=%E5%9C%B0%E4%B8%8A%E6%AC%8A&year=110&month1=0&begin_day=1&end_day=1&Orderby=1" r = requests.post(url, data=data)
soup = bs(r.text, 'html.parser')
soup.prettify()
list = []
t = soup.find("table")
for tr in t.find_all('tr'):
s = ""
for td in tr.find_all('td'):
s += td.text
if(s.replace(" ", "")!=""):
list.append(s)
for a in list:
print(a)
return list
使用requests做post 把要搜尋的參數以data丟入
得到的response(raw html)用bs4接 然後做需求目標做抓取並回傳一個指定內容的list
result:
5873 全球人壽 110/03/021 本公司董事會授權洽商國內不動產租賃事宜
6658 聯策 110/02/181 公告本公司取得不動產(簽訂買賣契約)
接著開始準備將成果發信的階段
參考 https://www.learncodewithmike.com/2020/02/python-email.html
取得Gmail應用程式密碼 接著跟著此文操作運作
import smtplibimport requestsimport pandasimport datetimeimport sysfrom bs4 import BeautifulSoup as bsfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom email.mime.image import MIMEImagefrom pathlib import Pathfrom string import Templatedef sendMail(content):with smtplib.SMTP(host="smtp.gmail.com", port="587") as smtp: # 設定SMTP伺服器try:smtp.ehlo() # 驗證SMTP伺服器smtp.starttls() # 建立加密傳輸smtp.login("*********", "********") # 登入寄件者gmailsmtp.send_message(content) # 寄送郵件print("Completed!")except Exception as e:print("Error message: ", e)sys.exit(1)def getInfo():# 上面已有 略
比較特別的是 這邊加了一個簡易的html表示我想表達的table
html = """\<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title></title><style type="text/css"></style></head><body style="margin:0; padding:0; background-color:#F2F2F2;"><p style="font-size:1.75vw"><b>以下為更新資訊</b> (關鍵字:不動產、地上權):</p><table width="100%" border="20" cellpadding="10" cellspacing="20" >"""
# 插入trfor s in info:html += "<tr><p style=\"font-size:1.5vw\">"+s+"</p></tr>"# 插入trhtml += """\</table><p style="font-size:1vw">Best Regards, <br>Max</p><img src="((skip))"/></body></html>"""
最後統整content 送出
content = MIMEMultipart() #建立MIMEMultipart物件content["subject"] = "[*業務用]公開資訊觀測站重大訊息通知" #郵件標題content["from"] = "*" #寄件者content["to"] = "*" #收件者content.attach(MIMEText(body, "html"))sendMail(content)
以非常簡易的方式產出一個email html template
成果