def get_key(): """ get public key, hash and session id for login. Returns: hash: salt for password encryption. pubkey: rsa public key for password encryption. sid: session id. """ headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': "application/json, text/javascript, */*; q=0.01" } post_data = { 'appkey': APPKEY, 'platform': "pc", 'ts': str(int(datetime.now().timestamp())) } post_data['sign'] = cipher.sign_dict(post_data, APPSECRET) r = requests.post("https://passport.bilibili.com/api/oauth2/getKey", headers=headers, data=post_data) r_data = r.json()['data'] return r_data['hash'], r_data['key'], r.cookies['sid']
def get_capcha(sid, file_name=None): headers = { 'User-Agent': '', 'Accept-Encoding': 'gzip,deflate', } params = { 'appkey': APPKEY, 'platform': 'pc', 'ts': str(int(datetime.now().timestamp())) } params['sign'] = cipher.sign_dict(params, APPSECRET) r = requests.get("https://passport.bilibili.com/captcha", headers=headers, params=params, cookies={'sid': sid}) print(r.status_code) capcha_data = r.content if file_name is not None: with open(file_name, 'wb+') as f: f.write(capcha_data) return r.cookies['JSESSIONID'], capcha_data
def upload_cover(self, cover_file_path): with open(cover_file_path, "rb") as f: cover_pic = f.read() headers = { 'Connection': 'keep-alive', 'Host': 'member.bilibili.com', 'Accept-Encoding': 'gzip,deflate', 'User-Agent': '', } params = { "access_key": self.access_token, } params["sign"] = cipher.sign_dict(params, APPSECRET) files = { 'file': ("cover.png", cover_pic, "Content-Type: image/png"), } r = requests.post( "http://member.bilibili.com/x/vu/client/cover/up", headers=headers, params=params, files=files, cookies={'sid': self.sid}, verify=False, ) return r.json()["data"]["url"]
def login_by_access_token(self, access_token, refresh_token=None): """ bilibili access token login. Args: access_token: Bilibili access token got by previous username/password login. """ self.access_token = access_token self.refresh_token = refresh_token headers = { 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip,deflate', 'Host': 'passport.bilibili.com', 'User-Agent': '', } login_params = { 'appkey': APPKEY, 'access_token': access_token, 'platform': "pc", 'ts': str(int(datetime.now().timestamp())), } login_params['sign'] = cipher.sign_dict(login_params, APPSECRET) r = requests.get(url="https://passport.bilibili.com/api/oauth2/info", headers=headers, params=login_params) print(r.json()) login_data = r.json()['data'] self.sid = r.cookies['sid'] self.mid = login_data['mid']
def login(self, username, password): """ bilibili login. Args: username: plain text username for bilibili. password: plain text password for bilibili. """ hash, pubkey, sid = get_key() encrypted_password = cipher.encrypt_login_password( password, hash, pubkey) url_encoded_username = parse.quote_plus(username) url_encoded_password = parse.quote_plus(encrypted_password) post_data = { 'appkey': APPKEY, 'password': url_encoded_password, 'platform': "pc", 'ts': str(int(datetime.now().timestamp())), 'username': url_encoded_username } post_data['sign'] = cipher.sign_dict(post_data, APPSECRET) # avoid multiple url parse post_data['username'] = username post_data['password'] = encrypted_password headers = { 'Connection': 'keep-alive', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'User-Agent': '', 'Accept-Encoding': 'gzip,deflate', } r = requests.post("https://passport.bilibili.com/api/oauth2/login", headers=headers, data=post_data, cookies={'sid': sid}) login_data = r.json()['data'] self.access_token = login_data['access_token'] self.refresh_token = login_data['refresh_token'] self.sid = sid self.mid = login_data['mid']
def do_token_refresh(self): """ bilibili login. Args: username: plain text username for bilibili. password: plain text password for bilibili. """ hash, pubkey, sid = get_key() post_data = { 'access_token': self.access_token, 'appkey': APPKEY, 'refresh_token': self.refresh_token, 'platform': "pc", 'ts': str(int(datetime.now().timestamp())), } post_data['sign'] = cipher.sign_dict(post_data, APPSECRET) headers = { 'Connection': 'keep-alive', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'User-Agent': '', 'Accept-Encoding': 'gzip,deflate', } r = requests.post( "https://passport.bilibili.com/api/oauth2/refreshToken", headers=headers, data=post_data, cookies={'sid': sid}) print(r.json()) login_data = r.json()['data'] self.access_token = login_data['access_token'] self.refresh_token = login_data['refresh_token'] self.sid = sid self.mid = login_data['mid']
def upload(self, parts, copyright: int, title: str, tid: int, tag: str, desc: str, source: str = '', cover: str = '', no_reprint: int = 0, open_elec: int = 1, max_retry: int = 5, thread_pool_workers: int = 1, timeout: int = 5): if not isinstance(parts, list): parts = [parts] self.parts = parts self.max_chunk_retry = 100 self.max_part_retry = max_retry self.chunk_timeout = timeout self.thread_pool_workers = thread_pool_workers with ThreadPoolExecutor(max_workers=thread_pool_workers) as tpe: t_list = [] for video_part in parts: print("upload {} added in pool".format(video_part.title)) t_obj = tpe.submit(self.upload_video_part_with_retry, video_part) t_obj.video_part = video_part t_list.append(t_obj) for t_obj in as_completed(t_list): print("video part {} finished, status: {}".format( t_obj.video_part.title, t_obj.result())) # cover if os.path.isfile(cover): try: cover = self.upload_cover(cover) except: cover = '' else: cover = '' # submit headers = { 'Connection': 'keep-alive', 'Content-Type': 'application/json', 'User-Agent': '', } post_data = { 'build': 1054, 'copyright': copyright, 'cover': cover, 'desc': desc, 'no_reprint': no_reprint, 'open_elec': open_elec, 'source': source, 'tag': tag, 'tid': tid, 'title': title, 'videos': [] } for video_part in parts: post_data['videos'].append({ "desc": video_part.desc, "filename": video_part.server_file_name, "title": video_part.title }) params = { 'access_key': self.access_token, } params['sign'] = cipher.sign_dict(params, APPSECRET) r = requests.post( url="http://member.bilibili.com/x/vu/client/add", params=params, headers=headers, verify=False, cookies={'sid': self.sid}, json=post_data, ) if not (r.status_code == 200 and r.json()['code'] == 0): raise RuntimeError(f"{r.status_code} {r.content.decode()}") print("submit", r.status_code, r.content.decode()) data = r.json()["data"] return data["aid"], data["bvid"]