JS实现b站动态评论区抽奖(含去重)

18 篇文章 3 订阅

新前言

    因为 b站动态升级原因,原来评论的页数也变成了无限下拉加载的形式,导致旧版程序无法使用,新版本的程序简单重构了一下,可参考下面的3.0版本新代码,使用方法一样,不过耗时会有所增加。
    目前成功完成1250 1w评论的动态的测试

补充

当然 感兴趣的可以去试试官方API
https://api.bilibili.com/x/v2/reply/main?callback=jQuery33106548244954033764_1618553940827&jsonp=jsonp&next=4&type=11&oid=130267145&mode=3&_=1618553940831
在这里插入图片描述
在这里插入图片描述
我这也简单分析一下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

动态转发抽奖可以参考这2篇文章
JS实现b站动态转发抽奖(小人数)新方案讲解
B站动态转发抽奖教程(python)

视频演示

JS实现b站动态评论区抽奖视频演示

旧前言

为了方便我已经对代码做了整理,传送门:码云 GitHub
测试页面链接:https://t.bilibili.com/394309046095520212?tab=2
动态评论数量为226,这个数量是全楼层的评论数量
在这里插入图片描述
共分为8页展示,一页首层人数20
在这里插入图片描述

教程

1、访问页面

PC端打开浏览器,访问你的动态抽奖页面。点在评论上,不用点转发。
在这里插入图片描述

2、打开“检查”

鼠标右键,打开“检查”,一般的快捷键都是F12
在这里插入图片描述
长这样,我们需要在console(控制台)下输入代码。

3、贴入代码

**评论记得翻到第一页!!!**超人性化设计,一步到位,还会打印所有用户名和ID,如果不需要可以注释掉打印代码,就是下面那些console.log代码,注释使用 // ,不会的可以自行百度JS注释。

console.log("程序开始运行");
console.log("定义集合存储数据");
let name_set = new Set();
let id_set = new Set();
console.log("开始载入数据");
var page = 1;
var my_loop;

// 抽奖函数
function draw()
{
    // 循环次数
    var len = document.getElementsByClassName("con").length;
	for(var i=0; i<len; i++)
	{
		var name = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].innerText;
		console.log(name+",加入集合");
		name_set.add(name);
		var id = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].getAttributeNode("data-usercard-mid").value;
		id_set.add(id);
	}
	console.log("第"+page+"页数据存入Set完毕");
	if(null != document.getElementsByClassName("next")[0])
	{
		page++;
		console.log("自动翻页...");
		document.getElementsByClassName("next")[0].click();
		//return true;
	}
	else
	{
		console.log("全部数据加载完毕");
		console.log("总共"+name_set.size+"名用户");
		// 生成随机数,直接打印中奖者信息
		var lucky_num = parseInt(Math.random()*(name_set.size),10);
		console.log("中奖用户ID为:"+Array.from(id_set)[lucky_num]);
		console.log("中奖用户名为:"+Array.from(name_set)[lucky_num]);
		console.log("中奖者大概位于 第" +parseInt(lucky_num/20+1)+ "页");
		clearInterval(my_loop);
		// 这就是注释
		//return false;
	}
}

// 定时调用函数
my_loop = setInterval(draw, 1500);

实际运行测试如下,如果评论人数较多或者网速较慢,请修改最后一行 my_loop = setInterval(draw, 1000); 把这里的1000调大,1000代表1s,这是自动翻页的时间。
在这里插入图片描述
10页数据加载完毕后,这就是中奖者信息
在这里插入图片描述

2.0版本多人抽取

运行完毕后,输入go(人数)即可
在这里插入图片描述

// 获取时间
function get_date() {
    var date = new Date();
	var h = date.getHours();
	var m = date.getMinutes();
	var s = date.getSeconds();
	h = h < 10 ? ('0' + h) : h;
	m = m < 10 ? ('0' + m) : m;
	s = s < 10 ? ('0' + s) : s;
    var currentDate = "[" + h + ":" + m + ":" + s + "] ";
    return currentDate;
}

// 从map获取下标为index的键
function get_map_key(map, index)
{
	var i = 0;
	for (var [key, value] of map) {
		if(i == index)
		{
			return key;
		}
		i++;
	}
}

// 从map获取下标为index的值
function get_map_value(map, index)
{
	var i = 0;
	for (var [key, value] of map) {
		if(i == index)
		{
			return value;
		}
		i++;
	}
}

// 遍历map
function get_map(map)
{
	for (var [key, value] of map) {
		console.log(key + " = " + value);
	}
}

console.log(get_date() + "程序开始运行");
console.log(get_date() + "定义图存储数据(自动去重)");
let name_map = new Map();
let id_map = new Map();
console.log(get_date() + "开始载入数据");
var page = 1;
var my_loop;

// 抽奖函数
function draw()
{
    // 循环次数
	var len = document.getElementsByClassName("con").length;
	for(var i=0; i<len; i++)
	{
		var name = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].innerText;
		var id = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].getAttributeNode("data-usercard-mid").value;
		//console.log(name+",加入图");
		name_map.set(name, page);
		id_map.set(id, page);
	}
	console.log(get_date() + "第"+page+"页数据存入Map完毕");
	if(null != document.getElementsByClassName("next")[0])
	{
		page++;
		//console.log("自动翻页...");
		document.getElementsByClassName("next")[0].click();
		//return true;
	}
	else
	{
		console.log(get_date() + "全部数据加载完毕");
		console.log(get_date() + "总共" + name_map.size + "名用户");
		clearInterval(my_loop);
		// 这就是注释
		//return false;
	}
}

function go(num)
{
	if(num > name_map.size)
	{
		console.log("???搞事情???,一共都没那么多人");
		return;
	}
	
	var arr = [];
	var lucky_num;
	for(var i = 0; i < num; i++)
	{
		lucky_num = parseInt(Math.random()*(name_map.size), 10);
		if (arr.toString().indexOf(lucky_num) > -1) {
			i--;
			continue;
		}
		else
		{
			arr.push(lucky_num);
		}

		console.log(" ");
		console.log("中奖用户ID为:" + get_map_key(id_map, lucky_num));
		console.log("中奖用户名为:" + get_map_key(name_map, lucky_num));
		console.log("中奖者位于页:" + get_map_value(name_map, lucky_num));
		console.log(" ");
	}
}

// 定时调用函数
my_loop = setInterval(draw, 1500);



3.0新版本单人抽取(适应b站动态改动)

使用方法相同,选中评论区后,console中贴入代码即可

console.log("程序开始运行");
console.log("定义集合存储数据");
let name_set = new Set();
let id_set = new Set();
console.log("开始载入数据");

// 循环变量
var my_loop;
// 下滑延时 500毫秒 网速/加载速度较慢的朋友们最好放慢速度 提高准确性
var r_time = 500;

// 评论数
var comment_num = parseInt(document.getElementsByClassName("text-offset")[1].innerText);

// 下滑
function r()
{
	window.scroll(0, 1920*comment_num);
	// 没有评论后自动停止下滑 并 抽奖
	if(document.getElementsByClassName("loading-state")[0].innerText == "没有更多评论")
	{
		// 停止下滑循环
		stop_r();
		// 抽奖函数
		draw();
	}
}

// 停止下滑循环
function stop_r()
{
	clearInterval(my_loop);
}

// 抽奖函数
function draw()
{
    // 循环次数
    var len = document.getElementsByClassName("con").length;
	for(var i=0; i<len; i++)
	{
		var name = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].innerText;
		// console.log(name+",加入集合");
		name_set.add(name);
		var id = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].getAttributeNode("data-usercard-mid").value;
		id_set.add(id);
	}
	
	console.log("全部数据加载完毕");
	console.log("总共"+name_set.size+"名用户");
	// 生成随机数,直接打印中奖者信息
	var lucky_num = parseInt(Math.random()*(name_set.size),10);
	console.log("中奖用户ID为:"+Array.from(id_set)[lucky_num]);
	console.log("中奖用户名为:"+Array.from(name_set)[lucky_num]);
	// 这就是注释
	//return false;
}

// 开始自动下滑 r_time毫秒一次
my_loop = setInterval(r, r_time);


3.1新版本多人抽取(适应b站动态改动)

数据加载完毕后,使用 go(中奖人数) 即可抽取

console.log("程序开始运行");
console.log("定义集合存储数据");
let name_set = new Set();
let id_set = new Set();
console.log("开始载入数据");

// 循环变量
var my_loop;
// 下滑延时 500毫秒 网速/加载速度较慢的朋友们最好放慢速度 提高准确性
var r_time = 500;

// 评论数
var comment_num = 1;
if(document.getElementsByClassName("text-offset")[1].innerText.indexOf("万") != -1)
{
	comment_num = 10000 * (parseInt(document.getElementsByClassName("text-offset")[1].innerText) + 1);
}
else
{
	comment_num = parseInt(document.getElementsByClassName("text-offset")[1].innerText);
}

// 下滑
function r()
{
	window.scroll(0, 1920*comment_num);
	// 没有评论后自动停止下滑 并 抽奖
	if(document.getElementsByClassName("loading-state")[0].innerText == "没有更多评论")
	{
		// 停止下滑循环
		stop_r();
		// 抽奖函数
		draw();
	}
}

// 停止下滑循环
function stop_r()
{
	clearInterval(my_loop);
}

// 抽奖函数
function draw()
{
    // 循环次数
    var len = document.getElementsByClassName("con").length;
	for(var i=0; i<len; i++)
	{
		var name = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].innerText;
		// console.log(name+",加入集合");
		name_set.add(name);
		var id = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].getAttributeNode("data-usercard-mid").value;
		id_set.add(id);
	}
	
	console.log("全部数据加载完毕");
	console.log("总共"+name_set.size+"名用户");
	
	// 这就是注释
	//return false;
}

// 获取幸运儿
function go(num)
{
	for(var i=0; i<num; i++)
	{
		// 生成随机数,直接打印中奖者信息
		var lucky_num = parseInt(Math.random()*(name_set.size), 10);

		console.log(" ");
		console.log("中奖用户ID为:"+Array.from(id_set)[lucky_num]);
		console.log("中奖用户名为:"+Array.from(name_set)[lucky_num]);
		console.log(" ");
	}
}

// 开始自动下滑 r_time毫秒一次
my_loop = setInterval(r, r_time);

// 全部数据加载完毕后,使用 go(中奖数) 抽取中奖者

3.2新动态版多人抽取优化css版本

考虑到大量数据对浏览器和电脑的压力,附加css样式禁用功能
效果如下:在这里插入图片描述

console.log("程序开始运行");

console.log("所有css样式禁用");
// 考虑到大量数据对浏览器和电脑的压力,附加css样式禁用功能
for(var i=0; i<document.styleSheets.length; i++)
{
	document.styleSheets[i].disabled = "disable";
}

console.log("定义集合存储数据");
let name_set = new Set();
let id_set = new Set();
console.log("开始载入数据");

// 循环变量
var my_loop;
// 下滑延时 500毫秒 网速/加载速度较慢的朋友们最好放慢速度 提高准确性
var r_time = 500;

// 评论数
var comment_num = 1;
if(document.getElementsByClassName("text-offset")[1].innerText.indexOf("万") != -1)
{
	comment_num = 10000 * (parseInt(document.getElementsByClassName("text-offset")[1].innerText) + 1);
}
else
{
	comment_num = parseInt(document.getElementsByClassName("text-offset")[1].innerText);
}

// 下滑
function r()
{
	window.scroll(0, 1920*comment_num);
	// 没有评论后自动停止下滑 并 抽奖
	if(document.getElementsByClassName("loading-state")[0].innerText == "没有更多评论")
	{
		// 停止下滑循环
		stop_r();
		// 抽奖函数
		draw();
	}
}

// 停止下滑循环
function stop_r()
{
	clearInterval(my_loop);
}

// 抽奖函数
function draw()
{
    // 循环次数
    var len = document.getElementsByClassName("con").length;
	for(var i=0; i<len; i++)
	{
		var name = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].innerText;
		// console.log(name+",加入集合");
		name_set.add(name);
		var id = document.getElementsByClassName("con")[i].getElementsByClassName("user")[0].getElementsByTagName("a")[0].getAttributeNode("data-usercard-mid").value;
		id_set.add(id);
	}
	
	console.log("全部数据加载完毕");
	console.log("总共"+name_set.size+"名用户");
	
	// 这就是注释
	//return false;
}

// 获取幸运儿
function go(num)
{
	for(var i=0; i<num; i++)
	{
		// 生成随机数,直接打印中奖者信息
		var lucky_num = parseInt(Math.random()*(name_set.size), 10);

		console.log(" ");
		console.log("中奖用户ID为:"+Array.from(id_set)[lucky_num]);
		console.log("中奖用户名为:"+Array.from(name_set)[lucky_num]);
		console.log(" ");
	}
}

// 开始自动下滑 r_time毫秒一次
my_loop = setInterval(r, r_time);

// 全部数据加载完毕后,使用 go(中奖数) 抽取中奖者

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love丶伊卡洛斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值