python B站原視頻爬取,最高清晰度爬取食呻。將你喜歡的up主的視頻保存下來吧流炕。

B站原視頻爬取,我就不多說直接上代碼仅胞。直接運行就好

B站是把視頻和音頻分開每辟。要把2個合并起來使用。這個需要分析才能看出來干旧。然后就是登陸這塊是比較難的渠欺。


import os
import re
import argparse
import subprocess
import prettytable
from DecryptLogin import login


'''B站類'''
class Bilibili():
    def __init__(self, username, password, **kwargs):
        self.username = username
        self.password = password
        self.session = Bilibili.login(username, password)
        self.headers = {
                        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36'
                    }
        self.user_info_url = 'http://api.bilibili.com/x/space/acc/info'
        self.submit_videos_url = 'http://space.bilibili.com/ajax/member/getSubmitVideos'
        self.view_url = 'http://api.bilibili.com/x/web-interface/view'
        self.video_player_url = 'http://api.bilibili.com/x/player/playurl'
    '''運行主程序'''
    def run(self):
        while True:
            userid = input('請輸入目標用戶ID(例:345993405) ——> ')
            user_info = self.__getUserInfo(userid)
            tb = prettytable.PrettyTable()
            tb.field_names = list(user_info.keys())
            tb.add_row(list(user_info.values()))
            print('獲取的用戶信息如下:')
            print(tb)
            is_download = input('是否下載該用戶的所有視頻(y/n, 默認: y) ——> ')
            if is_download == 'y' or is_download == 'yes' or not is_download:
                self.__downloadVideos(userid)
    '''根據(jù)userid獲得該用戶基本信息'''
    def __getUserInfo(self, userid):
        params = {'mid': userid, 'jsonp': 'jsonp'}
        res = self.session.get(self.user_info_url, params=params, headers=self.headers)
        res_json = res.json()
        user_info = {
                        '用戶名': res_json['data']['name'],
                        '性別': res_json['data']['sex'],
                        '個性簽名': res_json['data']['sign'],
                        '用戶等級': res_json['data']['level'],
                        '生日': res_json['data']['birthday']
                    }
        return user_info
    '''下載目標用戶的所有視頻'''
    def __downloadVideos(self, userid):
        if not os.path.exists(userid):
            os.mkdir(userid)
        # 非會員用戶只能下載到高清1080P
        quality = [('16', '流暢 360P'),
                   ('32', '清晰 480P'),
                   ('64', '高清 720P'),
                   ('74', '高清 720P60'),
                   ('80', '高清 1080P'),
                   ('112', '高清 1080P+'),
                   ('116', '高清 1080P60')][-3]
        # 獲得用戶的視頻基本信息
        video_info = {'aids': [], 'cid_parts': [], 'titles': [], 'links': [], 'down_flags': []}
        params = {'mid': userid, 'pagesize': 30, 'tid': 0, 'page': 1, 'order': 'pubdate'}
        while True:
            res = self.session.get(self.submit_videos_url, headers=self.headers, params=params)
            res_json = res.json()
            for item in res_json['data']['vlist']:
                video_info['aids'].append(item['aid'])
            if len(video_info['aids']) < int(res_json['data']['count']):
                params['page'] += 1
            else:
                break
        for aid in video_info['aids']:
            params = {'aid': aid}
            res = self.session.get(self.view_url, headers=self.headers, params=params)
            cid_part = []
            for page in res.json()['data']['pages']:
                cid_part.append([page['cid'], page['part']])
            video_info['cid_parts'].append(cid_part)
            title = res.json()['data']['title']
            title = re.sub(r"[‘’\/\\\:\*\?\"\<\>\|\s']", ' ', title)
            video_info['titles'].append(title)
        print('共獲取到用戶ID<%s>的<%d>個視頻...' % (userid, len(video_info['titles'])))
        for idx in range(len(video_info['titles'])):
            aid = video_info['aids'][idx]
            cid_part = video_info['cid_parts'][idx]
            link = []
            down_flag = False
            for cid, part in cid_part:
                params = {'avid': aid, 'cid': cid, 'qn': quality, 'otype': 'json', 'fnver': 0, 'fnval': 16}
                res = self.session.get(self.video_player_url, params=params, headers=self.headers)
                res_json = res.json()
                if 'dash' in res_json['data']:
                    down_flag = True
                    v, a = res_json['data']['dash']['video'][0], res_json['data']['dash']['audio'][0]
                    link_v = [v['baseUrl']]
                    link_a = [a['baseUrl']]
                    if v['backup_url']:
                        for item in v['backup_url']:
                            link_v.append(item)
                    if a['backup_url']:
                        for item in a['backup_url']:
                            link_a.append(item)
                    link = [link_v, link_a]
                else:
                    link = [res_json['data']['durl'][-1]['url']]
                    if res_json['data']['durl'][-1]['backup_url']:
                        for item in res_json['data']['durl'][-1]['backup_url']:
                            link.append(item)
                video_info['links'].append(link)
                video_info['down_flags'].append(down_flag)
        # 開始下載
        out_pipe_quiet = subprocess.PIPE
        out_pipe = None
        aria2c_path = os.path.join(os.getcwd(), 'tools/aria2c')
        ffmpeg_path = os.path.join(os.getcwd(), 'tools/ffmpeg')
        for idx in range(len(video_info['titles'])):
            title = video_info['titles'][idx]
            aid = video_info['aids'][idx]
            down_flag = video_info['down_flags'][idx]
            print('正在下載視頻<%s>...' % title)
            if down_flag:
                link_v, link_a = video_info['links'][idx]
                # --視頻
                url = '"{}"'.format('" "'.join(link_v))
                command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
                command = command.format(aria2c_path, len(link_v), userid, title+'.flv', aid, "", url)
                print(command)
                process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
                process.wait()
                # --音頻
                url = '"{}"'.format('" "'.join(link_a))
                command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
                command = command.format(aria2c_path, len(link_v), userid, title+'.aac', aid, "", url)
                print(command)

                process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
                process.wait()
                # --合并
                command = '{} -i "{}" -i "{}" -c copy -f mp4 -y "{}"'
                command = command.format(ffmpeg_path, os.path.join(userid, title+'.flv'), os.path.join(userid, title+'.aac'), os.path.join(userid, title+'.mp4'))
                print(command)

                process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe_quiet, shell=True)
                process.wait()
                os.remove(os.path.join(userid, title+'.flv'))
                os.remove(os.path.join(userid, title+'.aac'))
            else:
                link = video_info['links'][idx]
                url = '"{}"'.format('" "'.join(link))
                command = '{} -c -k 1M -x {} -d "{}" -o "{}" --referer="https://www.bilibili.com/video/av{}" {} {}'
                command = command.format(aria2c_path, len(link), userid, title+'.flv', aid, "", url)
                process = subprocess.Popen(command, stdout=out_pipe, stderr=out_pipe, shell=True)
                process.wait()
                os.rename(os.path.join(userid, title+'.flv'), os.path.join(userid, title+'.mp4'))
        print('所有視頻下載完成, 該用戶所有視頻保存在<%s>文件夾中...' % (userid))
    '''借助大佬開源的庫來登錄B站'''
    @staticmethod
    def login(username, password):
        _, session = login.Login().bilibili(username, password)
        return session


'''run'''
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='下載B站指定用戶的所有視頻(僅支持Windows下使用)')
    parser.add_argument('--username', dest='username', help='xxx', type=str, required=True)
    parser.add_argument('--password', dest='password', help='xxx', type=str, required=True)
    print(parser)
    args = parser.parse_args(['--password', 'xxx','--username', 'xxx'])
    # args = parser.parse_args(['--password', 'FOO'])
    bili = Bilibili(args.username, args.password)
    bili.run()

把賬號密碼填上就行。這是我根據(jù)一個微信公眾號Charles大佬的想法寫的椎眯。大家可以去關(guān)注他一下

點贊 收藏 謝謝咯 小紅書APP爬蟲也寫好了挠将,如果可以的話 我更新一下

有難點可以先加我QQ 1075762722麻煩先加個備注些胳岂。謝謝

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舔稀,隨后出現(xiàn)的幾起案子乳丰,更是在濱河造成了極大的恐慌,老刑警劉巖内贮,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件产园,死亡現(xiàn)場離奇詭異,居然都是意外死亡贺归,警方通過查閱死者的電腦和手機淆两,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拂酣,“玉大人秋冰,你說我怎么就攤上這事∩舭荆” “怎么了剑勾?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赵颅。 經(jīng)常有香客問我虽另,道長,這世上最難降的妖魔是什么饺谬? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任捂刺,我火速辦了婚禮,結(jié)果婚禮上募寨,老公的妹妹穿的比我還像新娘族展。我一直安慰自己,他們只是感情好拔鹰,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布仪缸。 她就那樣靜靜地躺著,像睡著了一般列肢。 火紅的嫁衣襯著肌膚如雪恰画。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天瓷马,我揣著相機與錄音拴还,去河邊找鬼。 笑死欧聘,一個胖子當著我的面吹牛自沧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼拇厢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了晒喷?” 一聲冷哼從身側(cè)響起孝偎,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凉敲,沒想到半個月后衣盾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡爷抓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年势决,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓝撇。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡果复,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渤昌,到底是詐尸還是另有隱情虽抄,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布独柑,位于F島的核電站迈窟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏忌栅。R本人自食惡果不足惜车酣,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望索绪。 院中可真熱鬧湖员,春花似錦、人聲如沸者春。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钱烟。三九已至晰筛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拴袭,已是汗流浹背读第。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拥刻,地道東北人怜瞒。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吴汪。 傳聞我的和親對象是個殘疾皇子惠窄,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345