日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

获取B站评论抽奖实现

發布時間:2024/3/26 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 获取B站评论抽奖实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

### 前景提要?

今天逛B站看了一個我喜歡的up主發的視屏,(音樂區up主)。然后視屏下面有人評論說要贊助抽些獎品。我就隨手寫了評論。要幫他寫抽獎。

完了之后想了下實現邏輯,億點都不難。只需要獲取到所有的評論信息,然后寫隨機數就可以了。

### 踩坑日記

然后我忙完手里的工作后用瀏覽器抓包看了下評論信息的URL。并試著用java請求。好吧失敗了。然后瀏覽器多抓了幾次包,分析瀏覽器請求。發現最后一位是隨機數,仔細看了好像是當前時間的毫秒值。然后我把數字轉成時間。好家伙。果然是當前請求的毫秒數。然后拼接參數后繼續請求。還是失敗。沒辦法只能繼續看請求了。發現中間有一段參數每次請求都會遞增,然后繼續組裝參數遞增。還是請求失敗

好吧我在想是不是判斷了我當前請求的客戶端是不是為瀏覽器。然后我設置了請求頭,結果還是失敗。

最后我想,肯定不止我一個人閑的沒事扒B站評論吶,看看別人是怎么扒的。然后我百度了一下。果然還是有很多人扒的,然后我發現,他們的請求居然沒有兩個會變得參數。然后我刪掉兩個參數后。what ? 請求到數據了。。。。

后面的工作就簡單多了,只需要將json格式的數據轉成我熟悉的java對象來操作就好了。

然后,B站返回的數據實在是太多了,一個身份信息就用了好多個字段,判斷是不是大會員呀之類的。好了我們用不到,那就先忽略吧,隨意拿了一些屬性出來構建實體。

### 代碼實現

import lombok.Data;/*** b 站視頻評論數據格式對象*/ @Data public class BiliBili {private Integer code;private String message;private Integer ttl;private BiliBiliData data; }

import lombok.Data; import java.util.List;/*** b 站視頻評論數據格式Data對象*/ @Data public class BiliBiliData {/*** 分頁信息*/private BiliBiliPage page;/*** 評論信息*/private List<BiliBiliReplies> replies; } import lombok.Data;/*** 分頁數據*/ @Data public class BiliBiliPage {private Integer count;private Integer num;private Integer size; }

import lombok.Data;import java.util.List;@Data public class BiliBiliReplies {private Integer rpid;private Integer oid;private Integer type;private Integer mid;private Integer root;private Integer parent;private Integer dialog;private Integer count;private Integer rcount;private Integer state;private Integer fansgrade;private Integer attr;private Integer ctime;private String rpid_str;private String root_str;private String parent_str;private Integer like;private Integer action;/*** 用戶信息*/private BiliBiliUser member;/*** 評論內容*/private BiliBiliComment content;/*** 下級評論*/private List<BiliBiliReplies> replies;} import lombok.Data;@Data public class BiliBiliUser {private String mid;private String uname;private String sex;private String sign;private String avatar;private String rank; } import lombok.Data;/*** b 站視頻評論內容爬取轉JSON*/ @Data public class BiliBiliComment {private String message; }

構建完這些實體,下面該實現抽獎的功能了

我用了hutool工具來做了json的轉換合http請求和集合的判斷

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.1</version> </dependency>

?昨天寫的時候評論比較少,評論沒有分頁今天發現默認的評論展示是每頁十條,所以添加了分頁的處理。原有基礎上添加了分頁的處理

import cn.hutool.core.collection.IterUtil; import cn.hutool.core.text.StrFormatter; import cn.hutool.http.HttpRequest; import cn.hutool.json.JSONUtil;import java.util.*; import java.util.stream.Collectors;public class BiliBiliCrawler {/*** 抽獎次數*/private static final Integer COUNT = 3;/*** 是否取消發布者的中獎資格 true 取消 false 不取消 .默認取消 哈哈*/private static final boolean IS_CANCEL = true;public static void main(String[] args) {String url = "https://api.bilibili.com/x/v2/reply/reply?&jsonp=jsonp&pn=1&type=1&oid=418654756&ps=10&root=4747243408";String str = HttpRequest.get(url).execute().body();// 轉java對象BiliBili bilibili = JSONUtil.toBean(str, BiliBili.class);// 獲取分頁信息BiliBiliPage page = bilibili.getData().getPage();// 計算頁數int total = (page.getCount() + page.getSize() - 1) / page.getSize();if (total == 0) {System.out.println("未獲取到評論信息");return;}// 用戶名集合List<String> list = new ArrayList<>(page.getCount());// 用戶評論集合,一個用戶可能存在多條評論信息Map<String, List<String>> con = new HashMap<>((int) Math.ceil(page.getCount() / 0.75) + 1);// 填充集合,準備抽獎for (int i = 1; i <= total; i++) {// 賦值頁碼,追加到評論之后,方便找到中獎者int a = i;// 第一次請求的數據在獲取頁數的時候就已經得到了所以第一次是不需要重新請求的BiliBili bili;if (i != 1) {String sf = StrFormatter.format("https://api.bilibili.com/x/v2/reply/reply?&jsonp=jsonp&pn={}&type=1&oid=418654756&ps=10&root=4747243408", i);String json = HttpRequest.get(sf).execute().body();// 轉java對象bili = JSONUtil.toBean(json, BiliBili.class);} else {bili = bilibili;}// 具體評論信息List<BiliBiliReplies> replies = bili.getData().getReplies();replies.forEach(e -> {// 是否取消發布者的中獎資格,并不了解B站各個字段是否具有對應關系,這里手動寫死if (IS_CANCEL && e.getMid().equals(447485021)) {return;// 跳出本次循環}String uname = e.getMember().getUname();list.add(uname);List<String> list1 = con.get(uname);if (IterUtil.isEmpty(list1)) {List<String> li = new ArrayList<>();li.add(e.getContent().getMessage() + " (評論所在頁碼:" + a + " )");con.put(uname, li);} else {list1.add(e.getContent().getMessage());}});}// 去除重復,保證每個人只有一次機會中獎,保證中獎幾率對等List<String> collect = list.stream().distinct().collect(Collectors.toList());// 抽獎次數大于等于評論人數,全部中獎,不需要抽取,人手一個if (COUNT >= collect.size()) {System.out.println("中獎人數列表: ");for (String userName : collect) {StringBuilder sb = new StringBuilder("中獎用戶名 : ");sb.append(userName);sb.append(" , 評論內容為 : [ ");List<String> list1 = con.get(userName);for (int i = 0; i < list1.size(); i++) {sb.append(list1.get(i));// 存在多條評論,用逗號分開if (i != list1.size() - 1) {sb.append(" || ");}}sb.append(" ]");System.out.println(sb.toString());}return;}// 打亂名單,使得中獎相對公平Collections.shuffle(list);// 循環抽取幸運用戶 ~System.out.println("中獎人數列表: ");for (int i = 0; i < COUNT; i++) {String userName = collect.remove(new Random().nextInt(collect.size()));StringBuilder sb = new StringBuilder("中獎用戶名 : ");sb.append(userName);sb.append(" , 評論內容為 : [ ");List<String> list1 = con.get(userName);for (int j = 0; j < list1.size(); j++) {sb.append(list1.get(j));// 存在多條評論,用 || 分開if (j != list1.size() - 1) {sb.append(" || ");}}sb.append(" ]");System.out.println(sb.toString());// 重新打亂集合Collections.shuffle(collect);}} }

### 實現效果(抽取三名)

第一次抽取 :

第二次抽取:

總結

以上是生活随笔為你收集整理的获取B站评论抽奖实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。