0101B站学习视频发留言找小伙伴-实用小工具系列

news2024/9/25 11:18:26

文章目录

    • 1 起因
    • 2 找方法
    • 3 bilibili_api
    • 4 实现
    • 5 知识点
    • 结语

1 起因

经常在B站看学习视频,但是一个人学习,偶尔在想,我学的怎么样?有没有用?有没有谁可以一起交流下?好在现在有互联网,可以极大的拉进彼此的“距离”。

那么怎么找到一些一起学习的小伙伴呢?想到“笨方法”就是在视频下面留言,留下联系方式。虽然有些大海捞针的感觉,但是总算有了方向。

2 找方法

因为之前学过爬虫的知识,想着这不是很简单吗?爬取下历史记录,获取视频下方留言框,模拟按钮发送留言,这不就完成了?

使用scrapy框架,创建工程-> 生成spider 省略,不熟悉的可以自行查阅相关文档或者看下之前的文章。

spiders/commonets.py代码如下

import scrapy


class CommentsSpider(scrapy.Spider):
    name = "comments"
    allowed_domains = ["bilibili.com"]
    start_urls = ["https://api.bilibili.com/x/web-interface/history/cursor"]
    headers = {
        'User-Agent': 'Baiduspider',
        'Cookie': "xxxx",
        'Referer': 'https://www.bilibili.com/account/history'
    }

    def parse(self, response):
        print(response.text)
        # histories = response.css('#history-list>li>.r-info>.r-txt>a::attr(href)').getall()
        # for history in histories:
        #     print(history)
        # pass

上来就遇到问题了,

{"code":-101,"message":"账号未登录","ttl":1}

直接添加cookie没有效果,上网找找有没有其他方法。

3 bilibili_api

网上搜索一番,找到一个不错的python库,地址在下面链接1。

这是一个用 Python 写的调用 Bilibili 各种 API 的库, 范围涵盖视频、音频、直播、动态、专栏、用户、番剧等[1]。

源码目录结构简介:

  • data

    • api:目录下为各种.json文件,存储要访问的url地址,示例

      {
          "info": {
            "url": "https://api.bilibili.com/x/space/wbi/acc/info",
            "method": "GET",
            "verify": false,
            "wbi": true,
            "params": {
              "mid": "int: uid"
            },
            "comment": "用户基本信息"
          },
       }
      
    • geetest:极验验证相关

  • excepitons:包内为封装的各种异常类

  • tools:各种工具

  • utils:封装各种工具方法或者类

  • *.py:封装各种对象和方法,比如user(用户),comment(评论),artile(文章)等等

4 实现

第一步:获取历史记录

既然要获取记录,那么肯定需要身份信息,这里封装为Credential对象,源代码如下3-1所示:

"""
bilibili_api.utils.Credential

凭据类,用于各种请求操作的验证。
"""

import json
from ..exceptions import (
    CredentialNoBiliJctException,
    CredentialNoSessdataException,
    CredentialNoBuvid3Exception,
    CredentialNoDedeUserIDException,
)
from .utils import get_api
import httpx
import uuid
from typing import Union

API = get_api("credential")


class Credential:
    """
    凭据类,用于各种请求操作的验证。
    """

    def __init__(
        self,
        sessdata: Union[str, None] = None,
        bili_jct: Union[str, None] = None,
        buvid3: Union[str, None] = None,
        dedeuserid: Union[str, None] = None,
    ):
        """
        各字段获取方式查看:https://nemo2011.github.io/bilibili-api/#/get-credential.md

        Args:
            sessdata   (str | None, optional): 浏览器 Cookies 中的 SESSDATA 字段值. Defaults to None.
            bili_jct   (str | None, optional): 浏览器 Cookies 中的 bili_jct 字段值. Defaults to None.
            buvid3     (str | None, optional): 浏览器 Cookies 中的 BUVID3 字段值. Defaults to None.
            dedeuserid (str | None, optional): 浏览器 Cookies 中的 DedeUserID 字段值. Defaults to None.
        """
        self.sessdata = sessdata
        self.bili_jct = bili_jct
        self.buvid3 = buvid3
        self.dedeuserid = dedeuserid

    def get_cookies(self):
        """
        获取请求 Cookies 字典

        Returns:
            dict: 请求 Cookies 字典
        """
        return {
            "SESSDATA": self.sessdata,
            "buvid3": self.buvid3 if self.buvid3 else str(uuid.uuid1()) + "infoc",
            "bili_jct": self.bili_jct,
            "DedeUserID": self.dedeuserid,
        }

    def has_dedeuserid(self):
        """
        是否提供 dedeuserid。

        Returns:
            bool。
        """
        return self.dedeuserid is not None

    def has_sessdata(self):
        """
        是否提供 sessdata。

        Returns:
            bool。
        """
        return self.sessdata is not None

    def has_bili_jct(self):
        """
        是否提供 bili_jct。

        Returns:
            bool。
        """
        return self.bili_jct is not None

    def has_buvid3(self):
        """
        是否提供 buvid3

        Returns:
            bool.
        """
        return self.buvid3 is not None

    def raise_for_no_sessdata(self):
        """
        没有提供 sessdata 则抛出异常。
        """
        if not self.has_sessdata():
            raise CredentialNoSessdataException()

    def raise_for_no_bili_jct(self):
        """
        没有提供 bili_jct 则抛出异常。
        """
        if not self.has_bili_jct():
            raise CredentialNoBiliJctException()

    def raise_for_no_buvid3(self):
        """
        没有提供 buvid3 时抛出异常。
        """
        if not self.has_buvid3():
            raise CredentialNoBuvid3Exception()

    def raise_for_no_dedeuserid(self):
        """
        没有提供 DedeUserID 时抛出异常。
        """
        if not self.has_dedeuserid():
            raise CredentialNoDedeUserIDException()

    async def check_valid(self):
        """
        检查 cookies 是否有效

        Returns:
            bool: cookies 是否有效
        """

        data = await get_nav(self)
        return data["isLogin"]

    def generate_buvid3(self):
        """
        生成 buvid3
        """
        self.buvid3 = str(uuid.uuid1()) + "infoc"


async def get_nav(credential: Union[Credential, None] = None, headers = None):
    """
    获取导航

    Returns:
        dict: 账号相关信息
    """

    api = API["valid"]
    try:
        cookies = None
        if credential is not None:
            cookies = credential.get_cookies()
        resp = httpx.request("GET", api["url"], cookies=cookies, headers=headers)
    except Exception as e:
        raise e
    return resp.json()["data"]
  • 主要是关于4个字段sessdata、bili_jct、buvid3、dedeuserid设置和获取。

  • 这几个信息,自动获取通过第三方库。手动获取需要我们登录B站后,在Application->Cookie中查找,如下图所示:

    在这里插入图片描述

第二步:在每个视频下面发一条评论

测试小代码如下所示:

import asyncio

import browser_cookie3
from bilibili_api import Credential, user, comment
from bilibili_api.comment import CommentResourceType


async def main() -> None:
    # 获取用户历史记录
    # 获取cookie
    cookies = browser_cookie3.chrome(domain_name='bilibili.com')
    # 创建凭据
    credential = Credential(sessdata=cookies['SESSDATA'], bili_jct=cookies['bili_jct'], buvid3=cookies['buvid3'], dedeuserid=cookies['DedeUserID'])
    # 创建用户
    # me = user.User(uid=17142789, credential=credential);
    info = await user.get_self_history(1, 100, credential)
    # print(len(info))
    # lists = await me.get_self_history()
    text = '欢迎小伙伴一起学习交流,有做笔记和代码练习,头像有联系方式和地址,一起加油啊[脱单doge][脱单doge][脱单doge]'
    for v in info:
        print(type(v['aid']))

        await comment.send_comment(text=text, oid=(v['aid']), type_=CommentResourceType.VIDEO, credential=credential)


if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())


示例效果,随便点开历史记录中一个视频,去下面评论留言查看,如下图所示:在这里插入图片描述

5 知识点

  • Credential:凭据(凭证类)
  • user.get_self_history():获取历史记录api
  • comment.send_commend():发送评论
  • CommentResourceType:评论资源类型枚举类
  • asyncio:异步IO

问题:

  1. 能正常发送评论了,但是有限制,报错提示验证码未通过。目前不确定它的校验机制,等以后慢慢探索下。

结语

欢迎小伙伴一起学习交流,需要啥工具或者有啥问题随时联系我。

❓QQ:806797785

⭐️源代码地址:https://gitee.com/gaogzhen/smart-utilities.git

[1]Nemo2011/bilibili-api[CP/OL]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/657700.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WiFi各协议理论速度

一、总览 二、11b到11g提升点 802.11g工作在2.4G频段下,能够支持OFDM和CCK两种调制方式,提供16-QAM、64-QAM、BPSK和QPSK四种编码方式,我们通常说的54Mbps速率就是在2.4G频段下,通过OFDM调制,采用64-QAM编码的情况下实…

表达式和语句

表达式 可以被求值的代码,并将其计算出一个结果 语句 一段可以执行的代码,是一个行为,例如分支语句和循环语句 三大流程控制语句 以前写的代码,写几句就从上往下执行 ,---顺序结构 有时候要根据条件 选择执行代码…

Spring源码之PostProcessor解析

系列文章目录 文章目录 系列文章目录前言一、PostProcessor是什么二、PostProcessor的作用三、Spring框架中有哪些PostProcessor呢BeanPostProcessorBeanFactoryPostProcessorInstantiationAwareBeanPostProcessorDestructionAwareBeanPostProcessorMergedBeanDefinitionPostPr…

Pinia 和 Vuex ,理解这两个 Vue 状态管理模式

Pinia和Vuex一样都是是vue的全局状态管理器。其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了这个看起来很甜的名字Pinia。 本文通过Vue3的形式对两者的不同实现方式进行对比,让你在以后工作中无论使用到Pinia还是Vuex的时候都能够游刃有余。 …

Linux下在日志中打印时间戳

1、背景介绍&#xff1a;在实验过程中需要记录任务运行情况&#xff0c;为此需要在日志中增加时间戳打印信息&#xff0c;方便事后查看。 2、实现方法 示例如下&#xff1a; #include <stdio.h> #include <time.h> #include<string.h>void print_debug_me…

如何在iPhone上用ChatGPT替换Siri

To use ChatGPT with Siri on an iPhone or iPad, get an OpenAI API key and download the ChatGPT Siri shortcut. Enter your API key in the shortcut setup and select the GPT model you want to use, then hit “Add Shortcut.” Trigger the shortcut manually first t…

FreeRTOS实时操作系统(二)系统文件代码学习

文章目录 前言系统配置任务创建任务创建删除实践 前言 接着学习正点原子的FreeRTOS教程&#xff0c;涉及到一些详细的系统内文件代码 系统配置 可以通过各种的宏定义来实现我们自己的RTOS配置&#xff08;在FreeRTOSconfig.h&#xff09; “INCLUDE”&#xff1a;配置API函数…

【Java】catch里面抛出了异常finally里面的事务会提交吗?

文章目录 背景目前的代码直接实战演示单元测试总结 背景 我们公司的系统中有一个业务场景&#xff0c;需要第三方的账户数据同步到我们系统。 同步账号的同时&#xff0c;会将所有同步数据和是否成功记录到一张同步日志表中&#xff0c;方便排查问题和记录。 好了&#xff0c;…

window11系统CUDA、cuDNN 安装以及环境变量配置

文章目录 一&#xff0c;说明二&#xff0c;cuda的下载以及安装1. 确定自己电脑设备哪个版本cudaa. 点击左下角b. 点击左下角c.接着点击 组件 2. cuda的下载3. cuda的安装1. 双击 点击 ok2. 同意即可3. 这个随意哪个都行4.选择安装位置 接着下一步 三&#xff0c;cuda环境变量设…

Oracle安装时先决条件检查失败和[INS-35180] 无法检查可用内存问题解决

Oracle安装时先决条件检查失败和[INS-35180] 无法检查可用内存问题解决 问题&#xff1a; [INS-13001] 此操作系统不支持 Oracle 数据库问题原因解决方案 问题2&#xff1a;[INS-35180] 无法检查可用内存问题原因解决方案 问题&#xff1a; [INS-13001] 此操作系统不支持 Oracl…

Python面向对象编程-构建游戏和GUI 手把手项目教学(1.1)

总项目目标&#xff1a;设计一个简单的纸牌游戏程序&#xff0c;称为"Higher or Lower"&#xff08;高还是低&#xff09;。游戏中&#xff0c;玩家需要猜测接下来的一张牌是比当前牌高还是低。根据猜测的准确性&#xff0c;玩家可以得到或失去相应的积分。 项目1.1…

循环码的编码、译码与循环冗余校验

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;https://github.com/timerring/information-theory 】或者公众号【AIShareLab】回复 信息论 获取。 文章目录 循环码的编码循环码…

实现 strStr

在一个串中查找是否出现过另一个串&#xff0c;这是KMP的看家本领。 28. 实现 strStr() 力扣题目链接 实现 strStr() 函数。 给定一个 haystack 字符串和一个 needle 字符串&#xff0c;在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在&…

七、docker-compose方式运行Jenkins,更新Jenkins版本,添加npm node环境

docker-compose方式运行Jenkins&#xff0c;更新Jenkins版本&#xff0c;添加npm node环境 一、docker-compose方式安装运行Jenkins 中发现Jenkins版本有点老&#xff0c;没有node环境&#xff0c;本节来说下更新jenkins 及添加构建前端的node环境。 1. 准备好docker-compose…

算法刷题-双指针-二分法

27. 移除元素 力扣题目链接 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并原地修改输入数组。 元素的顺序可以改变。你不需…

XSS数据接收平台——蓝莲花(BlueLotus)

文章目录 一、前言二、安装三、使用1、我的JS创建一个模板2、使用创建的模板攻击3、打开攻击的目标&#xff08;这里选择pikachu靶场的存储型XSS模块测试&#xff09;4、查看返回的数据 一、前言 蓝莲花平台是清华大学曾经的蓝莲花战队搭建的平台&#xff0c;该平台用于接收xs…

【QQ界面展示-通知的发布和监听 Objective-C语言】

一、来,看看,我们先给大家介绍一下通知 1.那么,这个通知,我们就是要给大家介绍三个东西 1)一个是通知的发布:如何发布通知 2)一个是通知的监听:发布以后,如何监听通知 3)一个是通知的移除:注意,通知一定要怎么样,最后,移除, 2.当你监听了一个通知以后,当你…

【Proteus仿真】51单片机+8255A IO扩展例程

【Proteus仿真】51单片机+8255A IO扩展例程 📍相关参考:51单片机8255A扩展IO口🎬Proteus仿真演示: 📓8255A与51单片机连接 🌿51单片机的P0口作为数据总线使用,与8255A的D7~D0数据信号线进行连接,当P00 - P07不作为8255A 的A、B、C端口地址使用时,可以不接上拉电阻…

3.部署glance服务(镜像获取组件)

身份认证服务部署完毕之后&#xff0c;部署 glance 映像服务&#xff0c;映像服务可以帮助用户发现、注册、检索虚拟机镜像&#xff0c;就是说 启动实例的镜像是放在这里的 。 默认镜像存储目录为&#xff1a; /var/lib/glance/images/ controller节点 在安装和配置 glance …

lua的元表与元方法理解

元表 在 Lua 中&#xff0c;元表&#xff08;metatable&#xff09;是一种特殊的表&#xff0c;用于定义另一个表的行为。每个表都有一个关联的元表&#xff0c;通过元表可以重载表的各种操作&#xff0c;例如索引、新索引、相加等。在 Lua 中&#xff0c;元表的使用非常灵活&…