馬哥原創,python全流程自動化:採集數據 -> 篩選數據 -> 存MySQL資料庫 -> 發送郵件 -> 微信提醒 -> 定時執行。 ...
目錄
一、概要
您好!我是@馬哥python說,一名10年程式猿。
我原創開發了一套定時自動化爬取方案,完整開發流程如下:
採集數據 -> 篩選數據 -> 存MySQL資料庫 -> 發送郵件 -> 微信提醒 -> 定時執行
如果您現在苦於每天繁瑣、重覆的數據採集工作,可嘗試套用該自動化方案,節省人力,降本增效!
二、效果演示
基於數據隱私保護,部分數據已脫敏。
圖2.1 MySQL資料庫結果(部分數據已脫敏):
圖2.2 Excel結果(部分數據已脫敏):
圖2.3 微信消息提醒:
圖2.4 收件箱告警郵件:
圖2.5 郵件正文內容(部分數據已脫敏):
以上。
三、代碼講解
3.1 爬蟲採集行政處罰數據
爬取目標是某公示平臺的行政處罰數據。
通過瀏覽器的開發者模式分析介面,頁面顯示數據與介面返回數據一致,故可通過爬取介面的方式採集。
圖3.1 開發者模式
首先,導入需要用到的庫:
import requests # 發送請求
import pandas as pd # 存取csv
import os # 判斷本地文件
import random # 隨機
from time import sleep # 等待時長,防止反爬
from sqlalchemy import create_engine # 連接資料庫
import json # 轉換數據格式
然後,定義請求頭(真實地址已脫敏):
# 請求頭
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Connection': 'keep-alive',
'Content-Type': 'application/json;charset=UTF-8',
'Cookie': '換成自己的cookie',
'Host': 'xxx',
'Origin': 'xxx',
'Referer': 'xxx',
'sec-ch-ua': '"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
定義請求參數,即開發者中的payload參數,不再展示。
發送post請求並接收返回數據:
# 發送post請求
r = requests.post(url, headers=headers, data=json.dumps(data))
# 查看響應碼
print(r.status_code)
# json解析數據
resp_json = r.json()
data_list = resp_json['data']['list']
逐個解析返回數據,以"處罰金額"為例:
for data in data_list:
# 處罰金額
punish_amount = data['f_2022118615143']
try:
if float(punish_amount) >= threshold: # 如果超過告警閾值,就存入數據
punish_amount_list.append(punish_amount)
else: # 否則進入下一輪迴圈
continue
except:
continue
這裡解釋一下:如果處罰金額超過事先設定好的閾值,則存入數據,否則不存,continue進入下一輪迴圈,由此達成告警的目的。
其他欄位(案件名稱、處罰人姓名、處罰日期、處罰機關等)同理,不再贅述代碼。
最後是保存數據到csv文件:
# 保存數據到Dataframe
df = pd.DataFrame(
{
'頁碼': page,
'案件名稱': case_name_list,
'處罰人姓名': punish_name_list,
'處罰金額': punish_amount_list,
'處罰日期': punish_time_list,
'處罰機關': punish_org_list,
}
)
# 保存到csv文件
df.to_csv(result_file, mode='a+', header=header, index=False, encoding='utf_8_sig')
數據存入csv效果,查看圖2.2。
3.2 存MySQL資料庫
如上所述,數據保存到csv文件作為臨時存儲,下麵保存到MySQL資料庫作為持久性存儲。
我採用sqlalchemy和pandas的to_sql結合的方式,把csv數據快速導入MySQL資料庫。
關鍵代碼(真實信息已脫敏):
# 創建MySQL資料庫連接
engine = create_engine('mysql+pymysql://用戶名:密碼@IP地址/資料庫名')
# 讀取csv數據
df_punish = pd.read_csv(result_file)
# 把csv數據導入MySQL資料庫
df_punish.to_sql(name='table_name', con=engine, chunksize=1000, if_exists='replace', index=False)
print('導入資料庫完成!')
這樣的簡單3行代碼,即實現了csv數據導入MySQL資料庫的目的。
註意,to_sql中的if_exists代表如果表中存在數據,那麼replace覆蓋原始數據,這樣不會產生重覆數據。當然,也可以加個ist_time插入時間的區分欄位,這樣可以把if_exists設置為append,保證每次爬取都留痕,你可以試試,我認為這樣代碼更完善、效果更好。
數據入庫效果,查看圖2.1。
3.3 發送告警郵件&微信通知
自動發送郵件,我採用zmail庫實現。
關鍵代碼(真實信息已脫敏):
def send_email(v_location, v_content):
# 當前時間戳
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 設置郵件信息
mail_content = {
'subject': '稅務行政處罰預警郵件 | {} | {}'.format(v_location, now), # 郵件標題
'content_text': '尊敬的管理員,您好!\n\n以下是【{}】稅務行政處罰預警名單,請註意查收。\n\n'.format(
v_location) + v_content # 郵件內容
}
# 發件人的用戶名和密碼
server = zmail.server('[email protected]', 'xxx') # 發件人
# 發送郵件
server.send_mail('[email protected]', mail_content) # 收件人
print('郵件已發送完畢:', v_location)
註意,發件人的smtp服務必須開啟,否則會郵件發送失敗,如下:
圖3.2 郵箱開啟smtp服務
郵件收到了,怎麼實現的微信通知呢?秘密就是把微信的郵件功能打開,如下:
圖3.3 微信設置
微信:我 -> 設置 -> 通用 -> 輔助功能 -> QQ郵箱提醒 -> 開啟功能
這樣就能讓微信收到消息提醒了,效果如圖2.3所示。
多說一句,請勿嘗試用itchat、wxpy等第三方庫操作微信,微信官方已停用這類工具,且存在封號風險!不信你就逝世![手動狗頭]
3.4 定時機制
定時執行也是採用簡單粗暴的方式,直接os.system調用分別的py文件,死迴圈加sleep的方式:
while True:
# 執行爬蟲
print(get_now(), '開始爬蟲!')
os.system('python 爬蟲.py')
print(get_now(), '爬取結束!')
sleep(1)
# 發郵件
print(get_now(), '開始發預警郵件!')
os.system('python 發預警郵件.py')
print(get_now(), '結束髮預警郵件!')
sleep(1)
# 等待時長60分鐘
print(get_now(), '開始等待60分鐘..')
sleep(3600)
這樣,程式只要在後臺一直運行就好了,每隔3600秒(即1小時)自動執行一次,可自定義設置間隔時長。
最終得到的效果就是每隔1小時微信收到一次消息通知,效果如圖2.3所示。
四、總結
這套定時採集通知方案,全流程均由本人原創開發,可套用到類似業務需求上,其中部分環節可根據需要,擴展相關功能。請小伙伴們打開腦洞,碼上開發!
如文中所說,部分信息涉及隱私保護,所以不提供完整代碼,有類似需求的小伙伴可私信討論。
我是@馬哥python說,一名10年程式猿,持續分享Python乾貨中!