DEV Community

Cover image for An easy method of f***ing annoying danmakus in videos on Bilibili
CreeperBlin
CreeperBlin

Posted on • Edited on

An easy method of f***ing annoying danmakus in videos on Bilibili

Update (1/18/23): Since Bilibili requires all requests sent via https, the content might have been out-of-date.

Warning

The program may trigger the security system of Bilibili if you send too much requests rapidly especially when you want to report danmakus, comments, etc.
The program is restricted for learning use. Do not use it to do anything against policies of Bilibili.
And the author is innocent for any third party use, legal or illegal.

0. Abstract

Because of the commercialization of Bilibili, a lot of new users joined it. These new users enriches the variety of the community but it turned out that this action has side effects. New users don't follow the rules and send danmakus subjectively. And it's annoying to see those meaningless danmakus. Here is a solution to it.

1.1 What makes a danmaku danmaku?

When a user sends a danmaku, he sends a requests to the server of Bilibili. And we can get history danmakus in xml format. For example:
<d p="490.19100,1,25,16777215,1584268892,0,a16f**dd,299508*****521095">蒙古上单对位击杀睿马一粥粘</d>
In this tag we can get some information including:

  • The time the danmaku can appear on screen;
  • The type of the danmaku;
  • The font size of danmaku;
  • The time stamp;
  • The pool the danmaku belongs to;
  • The encrypted uid of the user(a16f**dd);
  • The id of the danmaku(299508*****521095);
  • The content of danmaku;

And the last 3 items are all things we need!

1.2 How to get danmaku

To get the danmakus in a video, you need to call api of Bilibili.
Here is a method to get danmakus in a video.

def GetCid(bv):#convert bv to cid.
    headers={
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
    'Host':'api.bilibili.com',
    'content-type':'application/x-www-form-urlencoded'
    }
    data={}
    data.update(bvid=bv)
    #print(data)
    rslt=requests.get('http://api.bilibili.com/x/player/pagelist',headers=headers,
                      params=data,timeout=10)
    print(rslt.text)
    rsltJson=json.loads('['+rslt.text+']')
    cid=rsltJson[0]['data'][0]['cid']
    return cid

def GetDanmaku(cid):
    headers={
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
    'Host':'api.bilibili.com',
    'content-type':'application/x-www-form-urlencoded'
    }
    data={}
    data.update(oid=cid)
    rslt=requests.get('http://api.bilibili.com/x/v1/dm/list.so',headers=headers,
                      params=data,timeout=10)
    return rslt

Enter fullscreen mode Exit fullscreen mode

2.1 Preparations before reporting the danmakus

Before you report the danmakus, you need to log in to Bilibili.
Here is a method to get the info you need.

def loginQr():
    print('打开b站客户端,扫码并确认后关闭扫码窗口即可。')
    headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
    'Host':'passport.bilibili.com'
    }
    rslt=requests.get('http://passport.bilibili.com/qrcode/getLoginUrl',
                  headers=headers,timeout=10)
    urlJson=json.loads('['+rslt.text+']')
    url=urlJson[0]['data']['url']
    sp=os.getcwd()+'\\'
    myqr.run(words=url,
         version=1,
         level='M',
         save_dir=sp,
        )
    root=Tk()
    root.resizable(width='false', height='false')
    root.title='QrCode'
    label=Label(root,text='使用b站客户端扫码,扫完关掉窗口')
    label.grid(row=0,column=0)
    img=Image.open('qrcode.png')
    photo=ImageTk.PhotoImage(img)
    imglabel=Label(root,image=photo)
    imglabel.grid(row=1,column=0,columnspan=3)
    root.mainloop()
    return urlJson

def loginRslt(data):
    headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
    'Host':'passport.bilibili.com'
    }
    postData={}
    postData.update(oauthKey=data[0]['data']['oauthKey'])
    #print(postData)
    loginInfo=requests.post('http://passport.bilibili.com/qrcode/getLoginInfo',
                           headers=headers,data=postData,timeout=10)
    #print(loginInfo.text)
    #print(str(loginInfo.cookies))
    return loginInfo
loginInfo=loginRslt(loginQr())
sessdata=loginInfo.cookies['SESSDATA']
bili_jct=loginInfo.cookies['bili_jct']
Enter fullscreen mode Exit fullscreen mode

2.2 Report danmaku

def reportdm(key,csrf,dmid,cid):
    headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
    'Host':'api.bilibili.com',
    'content-type':'application/x-www-form-urlencoded'
    }
    c = {
    'csrf':csrf,
    'SESSDATA':key
    }
    postData={
    'csrf':csrf,
    'cid':cid,
    'dmid':dmid,
    'reason':'9'
    }
    rslt=requests.post('http://api.bilibili.com/x/dm/report/add',
                           cookies=c,headers=headers,data=postData,timeout=10)
    print(rslt.text)
Enter fullscreen mode Exit fullscreen mode

"csrf" is the bili_token.
"key" is the session data.

references:
https://github.com/SocialSisterYi/bilibili-API-collect

Download source code

Top comments (0)