访问热搜榜并发送邮件
访问微博热搜榜(微博搜索-热搜榜),获取微博热搜榜前50条热搜名称、链接及其实时热度,并将获取到的数据通过邮件的形式,每20秒发送一次到个人邮箱中。
一、 定义请求头
需要获取User-Agent、Accept、Accept-Language、Accept-Ecoding、Cookie五个字段,前四个字段可能都是相同的,主要是Cookie不同。具体获取流程如下:
1. 打开目标网页
https://s.weibo.com/top/summary
2. 按下F12进入开发者模式
此时页面如下:
3. 按下F5刷新页面
此时开发者模式中会有网页相关信息,页面如下:
4. 依次点击Network、All、以及summary(即目标链接的地址)
各个位置如下图所示:
5. 点击summary后出现右侧窗口,点击Header能够得到相关报文字段
如下图所示:
6. 所需的字段均在Request Header中
所需的字段即下图中标注的字段,具体字段对应的值以各自浏览器为主,无需与图中字段值相同。
7. 记下User-Agent、Accept、Accept-Language、Accept-Ecoding、Cookie五个字段值,后续在代码中会用到。
二、获取发送邮箱的smtp授权码
smtp授权码只需要发送邮箱的,不是接收邮箱的。因为不是自己主动发送邮件,通过第三方(python代码)发送的,所以需要获取smtp授权码进行第三方登录。本文以QQ邮箱为例,获取QQ邮箱的smtp授权码,其他类型邮箱类似或者可以上网查找相关资料。
1. 打开QQ邮箱设置 - 账户
下滑找到如图所示的选项。
2. 开启POP3/SMTP服务
具体操作步骤略,开启的时会有相关提示。
3. 生成授权码,并根据提示进行操作
4. 获得授权码
操作过后会得到下面的提示框,记住显示的授权码,备用。
三、其他说明
1. 注意事项
浏览微博热搜榜html网页源码可发现整个热搜榜内容均在<tbody>……</tbody>,每条热搜的信息(序号、关键词、热度)均在<tr>……</tr>标签内。
-
本文使用CSS选择器获取指定元素信息。
- 具体某条热搜链接和关键词的CSS选择器为:
-
#pl_top_realtimehot > table > tbody > tr:nth-child(1) > td.td-02 > a
- 为获取全部热搜的CSS选择器,将上面的改为:
-
#pl_top_realtimehot > table > tbody > tr> td.td-02 > a
- 同理,获取全部热搜热度的CSS选择器为:
-
#pl_top_realtimehot > table > tbody > tr > td.td-02 > span
热搜榜置顶没有显示热度,需要特殊处理。另外就是部分热搜的链接会出现别的情况,也需要特殊处理。具体处理方式参考下面代码。
2. 参考代码
# 爬虫相关模块
import requests
from bs4 import BeautifulSoup
# 发送邮箱相关模块
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 定时模块
import schedule
import time
# 请求网页
def page_request(url, header):
response = requests.get(url=url, headers=header)
html = response.content.decode("UTF-8")
return html
# 解析网页
def page_parse(html):
soup = BeautifulSoup(html, 'lxml')
news = []
# 处理热搜前50
urls_title = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > a')
hotness = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > span')
for i in range(len(urls_title)):
new = {}
title = urls_title[i].get_text()
url = urls_title[i].get('href')
# 个别链接会出现异常
if url == 'javascript:void(0);':
url = urls_title[i].get('href_to')
# 热搜top没有显示热度
if i == 0:
hot = 'top'
else:
hot = hotness[i - 1].get_text()
new['title'] = title
new['url'] = "https://s.weibo.com" + url
new['hot'] = hot
news.append(new)
print(len(news))
for element in news:
print(element['title'] + '\t' + element['hot'] + '\t' + element['url'])
# 发送邮件
sendMail(news)
# 将获取到的热搜信息发送到邮箱
def sendMail(news):
# 发送邮箱
from_addr = '发送邮箱'
# 发送邮箱授权码,不是邮箱密码,而是smtp授权码
password = '发送邮箱的smtp授权码'
# 接收邮箱
to_addr = '接收邮箱'
# qq邮箱的smtp地址
maihost = 'smtp.qq.com'
# 建立SMTP对象
qqmail = smtplib.SMTP()
# 25为SMTP常用端口
qqmail.connect(maihost, 25)
# 登录邮箱
qqmail.login(from_addr, password)
# 设置发送邮件的内容
content = ''
for i in range(len(news)):
content += str(i) + '、\t' + news[i]['title'] + '\t' + '热度:' + news[i]['hot'] + '\t' + '链接:' + news[i][
'url'] + ' \n'
get_time = time.strftime('%Y-%m-%d %X', time.localtime(time.time())) + '\n'
content += '获取事件时间为' + get_time
# 设置邮件的格式以及发送主题
msg = MIMEText(content, 'plain', 'utf-8')
msg['subject'] = Header('微博热搜', 'utf-8')
try:
qqmail.sendmail(from_addr, to_addr, msg.as_string())
print('succeed sending')
except:
print('fail sending')
qqmail.quit()
def job():
print('**************开始爬取微博热搜**************')
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Cookie': 根据各自的浏览器中显示的填写
}
url = 'https://s.weibo.com/top/summary'
html = page_request(url=url, header=header)
page_parse(html)
if __name__ == "__main__":
# 定时爬取,每隔20s爬取一次微博热搜榜并将爬取结果发送至个人邮箱
# 可以将20修改成其他时间
schedule.every(20).seconds.do(job)
while True:
schedule.run_pending()