利用 Python 自动抓取微博热搜,并定时发送至邮箱

访问微博热搜榜(微博搜索-热搜榜),获取微博热搜榜前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()
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值