An easy method of f***ing annoying danmakus in videos on Bilibili
Tags: python, bilibili, api, tutorial
Published: 2021-08-13 14:25:33

**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.
```python
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

```
## 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.
```python
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']
```
## 2.2 Report danmaku
```python
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)
```
"csrf" is the bili_token.
"key" is the session data.

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

[Download source code](https://github.com/creeper2333/bilibili-danmaku-auto-report)