一、前言
還有不到十天就是農歷新年了,看到一年來有許多的小伙伴關注我,尤其是下半年粉絲數增長了不少,博主還是很有成就感的,所以想為每一位粉絲發上一份郵件表示感謝。

園子的用戶賬號都是綁定郵箱的,但沒有顯式的給出每個用戶的郵箱,那么想要為每個粉絲發送郵件,只能一個個的發嘍,這當然不符合我們程序員的作風,我就想着能不能用程序批處理發送郵件。

二、獲取message接口
我們首先來看一下博客園官方的OpenAPI https://api.cnblogs.com/help看看有沒有發送郵件相關的接口說明,額......雖然其他的接口都給出了詳細的說明,但並沒有找到我想要的發送郵件接口,那只能通過瀏覽器親自動手查找嘍。
博主是火狐黨,這里就直接使用Firefox來查看吧。在發送短消息界面下,也就是上面的頁面下按F12進入開發者模式選擇網絡—XHR,就能找到當前向博客園服務器發送的請求。
關於XHR(XMLHttpRequest)這里給出w3cschool對其的說明https://www.w3cschool.cn/ajax/ajax-xmlhttprequest-send.html

這里我就先向自己的一個小號發送一條信息,看一下會產生一個什么樣的請求。
哦,原來是一個POST請求,請求地址是https://msg.cnblogs.com/api/message,那這樣就好辦的,我們再來有哪些參數。
三個參數正好對應收件人(name)、標題(title)和內容(content)。接口找到了我們的工作基本上就算是完成一半了。

三、爬取粉絲用戶名
第一個參數便是收件人的用戶名,這當然需要爬蟲來爬取,我們先來分析一下粉絲頁面。
以博主自己的粉絲頁為例,第一頁的URL為
https://home.cnblogs.com/u/wkfvawl/followers/
第二頁
https://home.cnblogs.com/u/wkfvawl/followers/?page=2
第三頁
https://home.cnblogs.com/u/wkfvawl/followers/?page=3
看到了吧,這個URL就是單純的page遞增,那么直接遍歷一下就可以了。
針對具體的一頁,查看HTML源碼
<li id="1fa4c2be-9d08-493d-e713-08d79458b333"> <a href="/u/1923713" title="鍾老師"> <div class="avatar_pic"> <img src="//pic.cnblogs.com/face/sample_face.gif" /> </div> <div class="avatar_name"> 鍾老師 </div> </a> <a class="edit hide" href="javascript:void(0)" onclick="delFollower('1fa4c2be-9d08-493d-e713-08d79458b333','鍾老師')">刪除粉絲</a> </li> <li id="0dc4b50d-5238-429c-04a0-08d704f23d44"> <a href="/u/MilkoSilver" title="星野妙"> <div class="avatar_pic"> <img src="//pic.cnblogs.com/face/1739984/20190711193403.png" /> </div> <div class="avatar_name"> 星野妙 </div> </a> <a class="edit hide" href="javascript:void(0)" onclick="delFollower('0dc4b50d-5238-429c-04a0-08d704f23d44','星野妙')">刪除粉絲</a> </li> <li id="bab9893e-b854-4ae3-4086-08d765b211a6"> <a href="/u/1870144" title="姚bing"> <div class="avatar_pic"> <img src="//pic.cnblogs.com/face/1870144/20200114195537.png" /> </div> <div class="avatar_name"> 姚bing </div> </a> <a class="edit hide" href="javascript:void(0)" onclick="delFollower('bab9893e-b854-4ae3-4086-08d765b211a6','姚bing')">刪除粉絲</a> </li> <li id="07d8642b-86b3-45fc-e4f5-08d79458b333"> <a href="/u/1922704" title="釋懷believe"> <div class="avatar_pic"> <img src="//pic.cnblogs.com/face/sample_face.gif" /> </div> <div class="avatar_name"> 釋懷believe </div> </a> <a class="edit hide" href="javascript:void(0)" onclick="delFollower('07d8642b-86b3-45fc-e4f5-08d79458b333','釋懷believe')">刪除粉絲</a> </li>
粉絲的用戶名是在 <div class="avatar_name">下,這里由於這個腳本是Python編寫,方便起見直接使用BeautifulSoup庫的find_all方法了,相信寫過Python爬蟲的朋友對這個解析工具應該是很熟悉了。
soup.find_all('div', attrs={'class': 'avatar_name'})
四、獲取Cookie
博客園是需要登錄的,為了讓我們的程序被博客園識別,需要獲得當前頁面的Cookie。而Cookie其實就藏在請求頭中。
五、Python實現
至此所有的准備都已經做好了,接下就是寫代碼了,主要就是requests庫的使用,這是Python的最為簡單易用的HTTP庫了,我們要做的工作就是先獲取用戶名接着構造請求參數,最后使用其的post方法發送請求。測試通過后會附上源代碼。
# coding=utf-8 import time import requests from bs4 import BeautifulSoup headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0', # 你登入的cookies 'Cookie': '********' } jsonDict = {"name": "test", "title": "博客園郵件群發功能測試", "content": "親愛的園友抱歉打擾了,博主正在進行博客園郵件群發功能的測試,該郵件權當做垃圾郵件,具體內容請見https://www.cnblogs.com/wkfvawl/p/12202859.html" } # 收件人名字,標題,內容 cnt = 1 urlSample = "https://home.cnblogs.com/followers/?page=" for page in range(1, 8): url = urlSample + str(page) # 構造新的url requests.packages.urllib3.disable_warnings() # 解決警告問題 html = requests.get(url, headers=headers, verify=False) soup = BeautifulSoup(html.content, 'lxml') links = soup.find_all('div', attrs={'class': 'avatar_name'}) for link in links: strings = link.string jsonDict['name'] = strings.replace(' ', '').replace('\n', '') res = requests.post('https://msg.cnblogs.com/api/message', json=jsonDict, headers=headers, verify=False) # post請求 print(res) time.sleep(60)#間隔60秒 print('第' + str(cnt) + '位粉絲') print(jsonDict) cnt = cnt + 1
剛才測試了一下將時間限制到10s發送一次請求還不行.....差不多1分鍾一個倒是可以....
