经常在B站看学习视频,但是一个人学习,偶尔在想,我学的怎么样?有没有用?有没有谁可以一起交流下?好在现在有互联网,可以极大的拉进彼此的“距离”。
那么怎么找到一些一起学习的小伙伴呢?想到“笨方法”就是在视频下面留言,留下联系方式。虽然有些大海捞针的感觉,但是总算有了方向。
因为之前学过爬虫的知识,想着这不是很简单吗?爬取下历史记录,获取视频下方留言框,模拟按钮发送留言,这不就完成了?
使用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没有效果,上网找找有没有其他方法。
网上搜索一番,找到一个不错的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(文章)等等
第一步:获取历史记录
既然要获取记录,那么肯定需要身份信息,这里封装为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())
示例效果,随便点开历史记录中一个视频,去下面评论留言查看,如下图所示:
问题:
欢迎小伙伴一起学习交流,需要啥工具或者有啥问题随时联系我。
❓QQ:806797785
⭐️源代码地址:https://gitee.com/gaogzhen/smart-utilities.git
[1]Nemo2011/bilibili-api[CP/OL]