JS实现b站动态转发抽奖(小人数)新方案讲解
经过大数据量测试后发现,程序不能爬取多转发人数的所有数据。原因是程序内API的数据不全,并没有提供所有的转发人员数据,导致数据的缺失。
测试数据量 转发人数6w+,而https://api.live.bilibili.com/dynamic_repost/v1/dynamic_repost/view_repost?dynamic_id=346409930135375313&offset= 只能到五百多就停了(即只能获取到最后转发的五百多人,不排除重复)。
1、连通的网络
2、已安装Python2并配置环境变量
3、Python脚本源码
网络就不用我说了(〃‘▽’〃) 那么下面我们来安装python吧。
Python官网有2个版本2和3,我们选择2,因为语法等方面会有所不同。
Python2下载:https://www.python.org/downloads/windows/
具体安装教学可百度,或参考 教程:https://www.runoob.com/python/python-install.html
记得要配置环境变量。
“计算机”右键-> “属性”->“高级系统设置”->“环境变量”-> 系统变量中找到“Path”->“编辑”->“新建”-> 将你python安装的路径粘贴进去-> 全部“确认”。
测试python是否配置完成。
按Win+R 键,输入“cmd”,“确认”。
桌面右键 -> “新建”-> “文本文档” -> 取名为 “抽奖.py”(不要隐藏文件扩展名)
修改正确后的图标是,而不是。
1、打开 “计算机”
2、点击这个箭头
3、选择 “查看”
4、勾上 “文件扩展名”
5、回到“桌面”,再次修改文件名。
感谢 Hack Inn大佬的脚本,下载网址:https://www.hackinn.com/index.php/archives/112/
文件建好后,我们贴入已经写好的代码:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
Bilibili动态转发抽奖脚本 V1.1
Auteur:Poc Sir Bilibili:鸟云厂商
Mon site Internet:https://www.hackinn.com
Weibo:Poc-Sir Twitter:@rtcatc
更新内容: 1.增加了对画册类型动态的支持。
"""
import os
import urllib2
import json
import sqlite3
import random
import webbrowser
import re
import time
from urlparse import *
def GetMiddleStr(content,startStr,endStr):
startIndex = content.index(startStr)
if startIndex>=0:
startIndex += len(startStr)
endIndex = content.index(endStr)
return content[startIndex:endIndex]
def GetUsers():
global Bilibili_Key
GetTotalRepost()
Tmp_count = 0
Bilibili_Key = 0
DynamicAPI = "https://api.live.bilibili.com/dynamic_repost/v1/dynamic_repost/view_repost?dynamic_id="+ Dynamic_id + "&offset="
conn = sqlite3.connect('Bilibili_TMP.db')
c = conn.cursor()
while Tmp_count<Total_count:
Tmp_DynamicAPI = DynamicAPI + str(Tmp_count)
try:
BiliJson = json.loads(GetMiddleStr(urllib2.urlopen(Tmp_DynamicAPI).read(),"comments\":",",\"total"))
for BiliJson_dict in BiliJson:
Bilibili_UID = str(BiliJson_dict['uid'])
Bilibili_Uname = BiliJson_dict['uname']
Bilibili_Comment = BiliJson_dict['comment']
Bilibili_Sql = "INSERT or REPLACE into Bilibili (UID,Uname,Comment,ID) VALUES (" + Bilibili_UID + ", '" + Bilibili_Uname + "', '" + Bilibili_Comment + "', " + str(Bilibili_Key) + ")"
c.execute(Bilibili_Sql)
conn.commit()
Bilibili_Key = Bilibili_Key + 1
except:
break
Tmp_count = Tmp_count + 20
else:
Tmp_count = 0
conn.close()
def GetTotalRepost():
global Total_count
global UP_UID
DynamicAPI = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=" + Dynamic_id
BiliJson = json.loads(urllib2.urlopen(DynamicAPI).read())
Total_count = BiliJson['data']['card']['desc']['repost']
UP_UID = BiliJson['data']['card']['desc']['user_profile']['info']['uid']
def GetLuckyDog():
Bilibili_Doge = random.randint(0,Bilibili_Key)
conn = sqlite3.connect('Bilibili_TMP.db')
c = conn.cursor()
cursor = c.execute("SELECT UID from Bilibili where ID=" + str(Bilibili_Doge))
res = cursor.fetchall()
suc = True
if len(res) > 0 :
suc = True
cursor.close()
conn.close()
conn2 = sqlite3.connect('Bilibili_TMP.db')
c2 = conn2.cursor()
info_cursor = c2.execute("SELECT UID,Uname,Comment from Bilibili where ID=" + str(Bilibili_Doge))
for row in info_cursor:
print " 用户ID: ", row[0]
print " 用户名: ", row[1]
print " 转发详情: ", row[2], "\n"
bilibili_open = raw_input(TellTime() + " 是否打开网页给获奖用户发送私信: (Y/N) ");
if bilibili_open == "Y":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "y":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "Yes":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "yes":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "是":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "是的":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
conn2.close()
else:
suc = False
cursor.close()
conn.close()
GetLuckyDog()
def DeleteDatabase():
DB_path = os.getcwd() + os.sep + "Bilibili_TMP.db"
try:
os.remove(DB_path)
print TellTime() + " 正在清理缓存..."
except:
print TellTime() + " 正在清理缓存..."
def CreateDatabase():
conn = sqlite3.connect('Bilibili_TMP.db')
c = conn.cursor()
c.execute('''CREATE TABLE Bilibili
(UID INT PRIMARY KEY NOT NULL,
Uname TEXT NOT NULL,
Comment TEXT NOT NULL,
ID INT NOT NULL);''')
conn.commit()
conn.close()
def GetDynamicid():
s = raw_input(" 请粘贴您获取到的网址: ")
nums = re.findall(r'\d+', s)
try:
bilibili_domain = urlparse(s)[1]
if bilibili_domain == "t.bilibili.com":
print TellTime() + " 为纯文本类型动态 "
return str(nums[0])
elif bilibili_domain == "h.bilibili.com":
bilibili_docid = "https://api.vc.bilibili.com/link_draw/v2/doc/dynamic_id?doc_id=" + str(nums[0])
Dynamic_id = GetMiddleStr(urllib2.urlopen(bilibili_docid).read(),"dynamic_id\":\"","\"}}")
print TellTime() + " 为画册类型动态 "
return str(Dynamic_id)
except:
print TellTime() + " 您输入的网址有误! "
exit()
def TellTime():
localtime = "[" + str(time.strftime('%H:%M:%S',time.localtime(time.time()))) + "]"
return localtime
if __name__ == '__main__':
DeleteDatabase()
print "+------------------------------------------------------------+"
print "|在电脑端登录Bilibli,点击进入个人主页,再点击动态,进入动态页面|"
print "|点击对应的动态内容,将获取到的网址复制,并粘贴在下方: |"
print "+------------------------------------------------------------+\n"
Dynamic_id = str(GetDynamicid())
TellTime()
print TellTime() + " 获取动态成功,ID为: " + Dynamic_id
print TellTime() + " 正在获取转发数据中......"
CreateDatabase()
GetUsers()
print TellTime() + " 获取数据成功! "
print TellTime() + " 中奖用户信息: \n"
GetLuckyDog()
DeleteDatabase()
以上就是源码部分。
贴入文件后 “保存” 退出。
按Win+R 键,输入 “cmd”,进入命令提示符,我们默认路径不在桌面,所以需要修改路径。输入“cd Desktop”,来到桌面,输入“chcp 65001”,再输入
“set PYTHONIOENCODING=utf-8”。然后输入“python 抽奖.py”运行程序。
然后贴入你的动态页面的网址。进入“b站”-> “动态” -> 找到自己要抽奖的那条动态 -> 复制网址 -> 粘贴到命令行中 -> “回车”即可
可能会碰到如下错误,是因为中文字符的原因,可以使用英文版。
提供下解决思路,将中文字符串前后都加个英文空格。
然后命令行依然需要输入
“chcp 65001”
“set PYTHONIOENCODING=utf-8”
然后运行程序 “python 文件名.py”
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
Bilibili动态转发抽奖脚本 V1.1
Auteur:Poc Sir Bilibili:鸟云厂商
Mon site Internet:https://www.hackinn.com
Weibo:Poc-Sir Twitter:@rtcatc
更新内容:1.增加了对画册类型动态的支持。
"""
import os
import urllib2
import json
import sqlite3
import random
import webbrowser
import re
import time
from urlparse import *
def GetMiddleStr(content,startStr,endStr):
startIndex = content.index(startStr)
if startIndex>=0:
startIndex += len(startStr)
endIndex = content.index(endStr)
return content[startIndex:endIndex]
def GetUsers():
global Bilibili_Key
GetTotalRepost()
Tmp_count = 0
Bilibili_Key = 0
DynamicAPI = "https://api.live.bilibili.com/dynamic_repost/v1/dynamic_repost/view_repost?dynamic_id="+ Dynamic_id + "&offset="
conn = sqlite3.connect('Bilibili_TMP.db')
c = conn.cursor()
while Tmp_count<Total_count:
Tmp_DynamicAPI = DynamicAPI + str(Tmp_count)
try:
BiliJson = json.loads(GetMiddleStr(urllib2.urlopen(Tmp_DynamicAPI).read(),"comments\":",",\"total"))
for BiliJson_dict in BiliJson:
Bilibili_UID = str(BiliJson_dict['uid'])
Bilibili_Uname = BiliJson_dict['uname']
Bilibili_Comment = BiliJson_dict['comment']
Bilibili_Sql = "INSERT or REPLACE into Bilibili (UID,Uname,Comment,ID) VALUES (" + Bilibili_UID + ", '" + Bilibili_Uname + "', '" + Bilibili_Comment + "', " + str(Bilibili_Key) + ")"
c.execute(Bilibili_Sql)
conn.commit()
Bilibili_Key = Bilibili_Key + 1
except:
break
Tmp_count = Tmp_count + 20
else:
Tmp_count = 0
conn.close()
def GetTotalRepost():
global Total_count
global UP_UID
DynamicAPI = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=" + Dynamic_id
BiliJson = json.loads(urllib2.urlopen(DynamicAPI).read())
Total_count = BiliJson['data']['card']['desc']['repost']
UP_UID = BiliJson['data']['card']['desc']['user_profile']['info']['uid']
def GetLuckyDog():
Bilibili_Doge = random.randint(0,Bilibili_Key)
conn = sqlite3.connect('Bilibili_TMP.db')
c = conn.cursor()
cursor = c.execute("SELECT UID from Bilibili where ID=" + str(Bilibili_Doge))
res = cursor.fetchall()
suc = True
if len(res) > 0 :
suc = True
cursor.close()
conn.close()
conn2 = sqlite3.connect('Bilibili_TMP.db')
c2 = conn2.cursor()
info_cursor = c2.execute("SELECT UID,Uname,Comment from Bilibili where ID=" + str(Bilibili_Doge))
for row in info_cursor:
print "user ID:", row[0]
print "user name:", row[1], "\n"
bilibili_open = raw_input(TellTime() + "Do you want to open a web page to send private messages to the winning users?:(Y/N)");
if bilibili_open == "Y":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "y":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "Yes":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "yes":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "是":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
elif bilibili_open == "是的":
webbrowser.open("https://message.bilibili.com/#/whisper/mid" + str(row[0]))
conn2.close()
else:
suc = False
cursor.close()
conn.close()
GetLuckyDog()
def DeleteDatabase():
DB_path = os.getcwd() + os.sep + "Bilibili_TMP.db"
try:
os.remove(DB_path)
print TellTime() + "Cleaning up cache..."
except:
print TellTime() + "Cleaning up cache..."
def CreateDatabase():
conn = sqlite3.connect('Bilibili_TMP.db')
c = conn.cursor()
c.execute('''CREATE TABLE Bilibili
(UID INT PRIMARY KEY NOT NULL,
Uname TEXT NOT NULL,
Comment TEXT NOT NULL,
ID INT NOT NULL);''')
conn.commit()
conn.close()
def GetDynamicid():
s = raw_input("Please paste the website you get:")
nums = re.findall(r'\d+', s)
try:
bilibili_domain = urlparse(s)[1]
if bilibili_domain == "t.bilibili.com":
print TellTime() + "Dynamic for plain text type"
return str(nums[0])
elif bilibili_domain == "h.bilibili.com":
bilibili_docid = "https://api.vc.bilibili.com/link_draw/v2/doc/dynamic_id?doc_id=" + str(nums[0])
Dynamic_id = GetMiddleStr(urllib2.urlopen(bilibili_docid).read(),"dynamic_id\":\"","\"}}")
print TellTime() + "Dynamic for album type"
return str(Dynamic_id)
except:
print TellTime() + "The URL you entered is incorrect!"
exit()
def TellTime():
localtime = "[" + str(time.strftime('%H:%M:%S',time.localtime(time.time()))) + "]"
return localtime
if __name__ == '__main__':
DeleteDatabase()
print "+---------------------------------------------------------------------------------------+"
print "|PC login Bilibli,in home page,Click on the news again,Enter the dynamic page |"
print "|Click the corresponding dynamic content, copy and paste the obtained URL below: |"
print "+---------------------------------------------------------------------------------------+\n"
Dynamic_id = str(GetDynamicid())
TellTime()
print TellTime() + "Get dynamic success with ID:" + Dynamic_id
print TellTime() + "Getting forwarding data......"
CreateDatabase()
GetUsers()
print TellTime() + "Data acquisition successful!"
print TellTime() + "Winning user information:\n"
GetLuckyDog()
DeleteDatabase()
使用操作是不需要修改编码,直接win+R,运行cmd,然后cd到桌面,运行python文件,粘贴入你的动态页面网址,就可以完成抽奖了。之后可以选择是否私信,很方便。再次感谢Hack Inn大佬提供的源码。
动态转发抽奖.py 是英文版
动态转发抽奖2.py 是中文版
如果想看所有转发者的数据,可以下载SQLiteSpy可视化工具或安装SQLite数据库,打开Bilibili_TMP.db文件(存储数据的数据库文件)
SQLite官网:https://www.sqlite.org/index.html
SQLite安装教程:https://www.runoob.com/sqlite/sqlite-installation.html
此时不要继续操作。在运行路径下可以看到文件Bilibili_TMP.db。
运行我们的 SQLiteSpy
file -> open database
打开我们的 Bilibili_TMP.db
双击table下的bilibili
数据库中的数据就可以看到了
现在可以自行进行筛选,如运用SQL语句进行筛选。
比如:select * from Bilibili where Comment!="转发动态"
除去只转发没有说多余话的人。效果如下:
执行SQL语句的方法是在上面的框中输入SQL语句,然后按F9(execute->execute sql)运行SQL语句。
就可以看到执行效果了。
SQL语句的学习参考:数据库的相关知识—学习笔记,SQL数据查询语言—实际运用参考
如需帮助可联系up
b站:Love丶伊卡洛斯
QQ: 327209194
QQ群:511921385
侵删同样联系方式如上。