博客园向粉丝群发邮件功能测试
一、前言
还有不到十天就是农历新年了,看到一年来有许多的小伙伴关注我,尤其是下半年粉丝数增长了不少,博主还是很有成就感的,所以想为每一位粉丝发上一份邮件表示感谢。
园子的用户账号都是绑定邮箱的,但没有显式的给出每个用户的邮箱,那么想要为每个粉丝发送邮件,只能一个个的发喽,这当然不符合我们程序员的作风,我就想着能不能用程序批处理发送邮件。
二、获取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分钟一个倒是可以....