def post_comment(self, session_dict: {str: str}) -> bool: if (datetime.datetime.now(datetime.timezone.utc) - self.start_date).total_seconds() / 60 / 60 > HOURS_THRESHOLD: return True if self.session_id not in session_dict: return False if self.error_count > ERROR_THRESHOLD: return True bvid = session_dict[self.session_id] try: video.get_video_info(bvid) except bilibili_api.exceptions.BilibiliApiException: # Video not published yet return False print(f"posting comments on {bvid}") self.error_count += 1 verify = Verify(self.sessdata, self.csrf) # load sc and se text with open(self.sc_path, 'r') as file: # sc_str = process_text(file.read(), bvid) sc_str = file.read() with open(self.he_path, 'r') as file: # he_str = process_text(file.read(), bvid) he_str = file.read() sc_list = sc_str.split(SEG_CHAR) he_list = he_str.split(SEG_CHAR) try: if self.he_root_id == "": resp = send_comment(he_list[0], bvid=bvid, verify=verify) self.he_root_id = resp['rpid'] self.he_progress = 1 for i, content in enumerate(he_list): if i >= self.he_progress: send_comment(content, bvid=bvid, root=self.he_root_id, verify=verify) self.he_progress = i + 1 if self.sc_root_id == "": resp = send_comment(sc_list[0], bvid=bvid, verify=verify) self.sc_root_id = resp['rpid'] self.sc_progress = 1 for i, content in enumerate(sc_list): if i >= self.sc_progress: send_comment(content, bvid=bvid, root=self.sc_root_id, verify=verify) self.sc_progress = i + 1 except bilibili_api.exceptions.BilibiliApiException: print("Comment posting failed") print(print(traceback.format_exc())) return False return True
def video_uploader(self): asyncio.set_event_loop(self.video_uploading_loop) while True: upload_task = self.video_upload_queue.get() try: first_video_comment = upload_task.session_id not in self.save.session_id_map bv_id = upload_task.upload(self.save.session_id_map) sys.stdout.flush() with self.save_lock: self.save.session_id_map[upload_task.session_id] = bv_id self.save_progress() if first_video_comment: self.comment_post_queue.put( CommentTask.from_upload_task(upload_task)) v_info = video.get_video_info(bvid=bv_id, is_simple=False, is_member=True, verify=upload_task.verify) cid = v_info['videos'][0]['cid'] print("adding subtitle task to queue") self.subtitle_post_queue.put( SubtitleTask.from_upload_task(upload_task, bv_id, cid)) except Exception: if upload_task.trial < 5: upload_task.trial += 1 self.video_upload_queue.put(upload_task) print(f"Upload failed: {upload_task.title}, retrying") else: print(f"Upload failed too many times: {upload_task.title}") print(traceback.format_exc())
def getInfo(url, rank): bvid = getBvid(url) video_info = video.get_video_info(bvid=bvid) #获取视频cid cid = video_info["cid"] #弹幕 danmu = getDanmu(cid) #标题 title = video_info["title"] #播放量 play = video_info["stat"]["view"] #弹幕数量 danmu_num = video_info["stat"]["danmaku"] #作者 author = video_info["owner"]["name"] info = { "排名": rank, "标题": title, "链接": url, "播放量": play, "弹幕数量": danmu_num, "作者": author, "ChatId": cid, "弹幕": danmu } return info
def getDM(bvid): Mode = input("选择模式(1:全弹幕/2:全分词)\n") info = video.get_video_info(bvid=bvid) data = { 'bvid': info['bvid'], 'cid': info['cid'], 'ownerName': info['owner']['name'], 'videoName': info['title'], 'DM': [], 'mode': "" } url = "https://api.bilibili.com/x/v1/dm/list.so?oid=" + str(info['cid']) response = requests.get(url=url) response.encoding = response.apparent_encoding select = BeautifulSoup(response.text, 'html.parser') DMdata = [s.get_text() for s in select.find("i").find_all('d')] if Mode == "1": str1 = ' '.join(DMdata) data['mode'] = "全弹幕" else: str1 = ''.join(DMdata) str1 = ' '.join(jieba.lcut_for_search(str1)) data['mode'] = "全分词" data['DM'] = str1 return data
def post_subtitle(self) -> bool: if (datetime.datetime.now(datetime.timezone.utc) - self.start_date).total_seconds() / 60 / 60 > HOURS_THRESHOLD: return True if self.error_count > ERROR_THRESHOLD: return True try: video.get_video_info(self.bvid) except bilibili_api.exceptions.BilibiliApiException: # Video not published yet return False self.error_count += 1 verify = Verify(self.sessdata, self.csrf) with open(self.subtitle_path) as srt_file: srt_obj = srt.parse(srt_file.read()) srt_json = { "font_size": 0.4, "font_color": "#FFFFFF", "background_alpha": 0.5, "background_color": "#9C27B0", "Stroke": "none", "body": [] } for srt_single_obj in srt_obj: srt_single_obj: srt.Subtitle srt_single_obj_body = { "from": srt_single_obj.start.total_seconds(), "to": srt_single_obj.end.total_seconds(), "location": 2, "content": srt_single_obj.content } srt_json["body"] += [srt_single_obj_body] srt_json_str = json.dumps(srt_json) print(f"posting subtitles on {self.cid} of {self.bvid}") try: video.save_subtitle(srt_json_str, bvid=self.bvid, cid=self.cid, verify=verify) except bilibili_api.exceptions.BilibiliApiException as e: # noinspection PyUnresolvedReferences if hasattr(e, 'code') and (e.code == 79022 or e.code == -404 or e.code == 502): # video not approved yet self.error_count -= 1 return False else: print(traceback.format_exc()) return False return True
def parse(self, response): items = BilibiliListScrItem() lists = response.xpath('//div[@id="app"]/div[2]/div[2]/ul/li') for i in lists: items['date'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) items['type'] = 'all' items['rank'] = i.xpath('./div[2]/div[2]/div[2]/div/text()').get() items['url'] = i.xpath('./div[2]/div[1]/a/@href').get()[2:] # items['pic'] = i.xpath('./div[2]/div[1]/a/img/@data-src').get() items['name'] = i.xpath('./div[2]/div[2]/a/text()').get() items['bv'] = i.xpath('./div[2]/div[1]/a/@href').get()[25:] v = video.get_video_info(bvid=items['bv']) items['pic'] = v['pic'] items['aid'] = v['aid'] items['view'] = v['stat']['view'] items['up'] = v['owner']['name'] items['upId'] = v['owner']['mid'] yield items # 补充更新同up主多数据爬取 lists = response.xpath( '//*[@id="app"]/div[2]/div[2]/ul/li/div[2]/div[3]/div/a') for i in lists: items['date'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) items['type'] = 'all' items['rank'] = i.xpath('./strong/text()').get() items['url'] = i.xpath('./@href').get()[2:] # items['pic'] = i.xpath('./div[2]/div[1]/a/img/@data-src').get() items['name'] = i.xpath('./span/text()').get() items['bv'] = i.xpath('./@href').get()[25:] v = video.get_video_info(bvid=items['bv']) items['pic'] = v['pic'] items['aid'] = v['aid'] items['view'] = v['stat']['view'] items['up'] = v['owner']['name'] items['upId'] = v['owner']['mid'] yield items
def video_confirm(): bv = var_bvid.get() if bv is None: tkinter.messagebox.showwarning(message='请填写bv号') elif ver is None: tkinter.messagebox.showwarning(message='请先验证!') else: if bv[:4] == 'http' or bv[:3] == 'www': bv = re.search("/BV[\w]*\?", bv).group()[1:-1] comp_info = video.get_video_info(bvid=bv, is_simple=False, verify=ver) render = get_pic(comp_info['pic'], 400, 250) info_window = tk.Toplevel() info_window.title('视频详情') info_window.geometry('800x800') img_display = tk.Label(info_window, image=render) img_display.place(x=20, y=50) title = tk.Label(info_window, text='标题: ' + comp_info['title'], font=("微软雅黑", 14, "bold"), height=1) describe = scrolledtext.ScrolledText(info_window, font=("微软雅黑", 10), height=7) describe.insert(tk.INSERT, comp_info['desc']) describe.config(state=tk.DISABLED) describe.place(x=50, y=380) tag = tk.Label(info_window, text='标签:' + comp_info['tname'], font=("微软雅黑", 10, "bold"), height=2) describe_label = tk.Label(info_window, text='简介:', font=("微软雅黑", 12, "bold"), height=2) dynamic = tk.Label(info_window, text='动态:' + comp_info['dynamic'], font=("微软雅黑", 10, "bold"), height=2) likes = str(comp_info['stat']['like']) coins = str(comp_info['stat']['coin']) fav = str(comp_info['stat']['favorite']) # state = tk.Label(info_window, text='点赞:' + likes + ' 硬币:' + coins + ' 收藏:' + fav, font=("微软雅黑", 10, "bold"), height=2) title.pack() describe_label.place(x=325, y=320) tag.place(x=450, y=50) dynamic.place(x=450, y=100) state.place(x=450, y=150) button_c_s = tk.Button(info_window, text="点赞", command=b_set_like) button_c_s.place(x=100, y=520) button_c_s = tk.Button(info_window, text="投币", command=b_add_coin) button_c_s.place(x=200, y=520) button_c_s = tk.Button(info_window, text="获取收藏列表", command=lambda: set_fav_list(info_window)) button_c_s.place(x=300, y=520) info_window.mainloop()
def post_comment(bv_number: str, sc_comments: [str], he_comments: [str], config: {str: str}) -> bool: try: verify = Verify(sessdata=config["sessdata"], csrf=config["bili_jct"]) _ = get_video_info(bvid=bv_number, verify=verify) try: post_comments_on_vid(bv_number, sc_comments, verify) post_comments_on_vid(bv_number, he_comments, verify) except bilibili_api.exceptions.BilibiliApiException: print("comment posting error", file=sys.stderr) print(traceback.format_exc(), file=sys.stderr) finally: return True except bilibili_api.exceptions.BilibiliApiException: return False
from bilibili_api import video import json v = video.get_video_info(bvid="BV1uv411q7Mv") print(json.dumps(v, indent=4, ensure_ascii=False))
def upload_video(image_path, video_path, date_string, uploader_name, title, config, update_mode, task_id): verify = Verify(sessdata=config["sessdata"], csrf=config["bili_jct"]) video_date = dateutil.parser.isoparse(date_string) history_names = [ video_name for task_id, (bvid, video_name) in upload_task_dict.items() ] video_name = f"【{uploader_name}】{video_date.strftime('%Y年%m月%d日')} {title} 无弹幕先行版" i = 1 while video_name in history_names: i += 1 video_name = f"【{uploader_name}】{video_date.strftime('%Y年%m月%d日')} {title}{i} 无弹幕先行版" cover_url = video_cover_upload(image_path, verify=verify) def on_progress(update): print(update, file=sys.stderr) filename = video_upload(video_path, verify=verify, on_progress=on_progress) if not update_mode: data = { "copyright": 2, "source": config["source"], "cover": cover_url, "desc": config["description"] + f"\nhttps://tsxk.jya.ng/{video_path}", "desc_format_id": 0, "dynamic": "", "interactive": 0, "no_reprint": 0, "subtitles": { "lan": "", "open": 0 }, "tag": config["tags"], "tid": config["channel_id"], "title": video_name, "videos": [{ "desc": "", "filename": filename, "title": video_name }] } result = video_submit(data, verify) print(f"{video_name} uploaded: {result}", file=sys.stderr) upload_task_dict[task_id] = (result['bvid'], video_name) update_upload_task_dict() return result else: v = get_video_info(bvid=upload_task_dict[task_id], is_simple=False, is_member=True, verify=verify) print(f"updating... original_video: {v}", file=sys.stderr) data = { "copyright": v["archive"]['copyright'], "source": v["archive"]["source"], "cover": v["archive"]["cover"], "desc": v["archive"]["desc"], "desc_format_id": v["archive"]["desc_format_id"], "dynamic": v["archive"]["dynamic"], # "interactive": v["archive"]["interactive"], # "no_reprint": v["archive"]["no_reprint"], # "subtitle": v["subtitle"], "tag": v["archive"]["tag"], "tid": v["archive"]["tid"], "title": v["archive"]["title"].replace("无弹幕先行版", "弹幕高能版"), "videos": [{ "desc": video['desc'], "filename": filename if idx == 0 else video['filename'], "title": video['title'] } for idx, video in enumerate(v["videos"])], "handle_staff": False, 'bvid': v["archive"]["bvid"] } result = video_update(data, verify) print(f"{data['title']} updated: {result}", file=sys.stderr) return result
from bilibili_api import video # put BVs in BV.txt file = open('BV.txt', 'r') while True: bv = file.readline() if not bv: break v = video.get_video_info(bvid=bv.rstrip()) title = v['title'] views = v['stat']['view'] likes = v['stat']['like'] comments = v['stat']['reply'] print(f"Title: {title}") print(f" Views: {views}") print(f" Likes: {likes}") print(f" Comments: {comments}")
from bilibili_api import video import re import pandas as pd # BVid、fileName BVid = input("输入BV号") # 获取弹幕 my_video = video.get_video_info(bvid=BVid) file_name = BVid + '.csv' danmu = video.get_danmaku(bvid=BVid) data = [data.text for data in danmu] for i in data: i = re.sub('\s+', '', i) print("弹幕数量为:{}".format(len(data))) df = pd.DataFrame(data) df.to_csv(file_name, index=False, header=None, encoding="utf_8_sig") print("写入文件成功")
def upload(self, session_dict: {str: str}): def on_progress(update): print(update) filename = video_upload(self.video_path, verify=self.verify, on_progress=on_progress) if self.danmaku: suffix = "弹幕高能版" else: suffix = "无弹幕版" if self.session_id not in session_dict: cover_url = video_cover_upload(self.thumbnail_path, verify=self.verify) data = { "copyright": 2, "source": self.source, "cover": cover_url, "desc": self.description, "desc_format_id": 0, "dynamic": "", "interactive": 0, "no_reprint": 0, "subtitles": { "lan": "", "open": 0 }, "tag": self.tag, "tid": self.channel_id, "title": self.title + SPECIAL_SPACE + suffix, "videos": [{ "desc": "", "filename": filename, "title": suffix }] } result = video_submit(data, self.verify) print(f"{self.title} uploaded: {result}") return result['bvid'] else: old_bv = session_dict[self.session_id] v = get_video_info(bvid=old_bv, is_simple=False, is_member=True, verify=self.verify) old_title = v["archive"]["title"] if SPECIAL_SPACE in old_title: stripped_title = old_title.rpartition(SPECIAL_SPACE)[0] else: stripped_title = old_title new_title = stripped_title + SPECIAL_SPACE + suffix data = { "copyright": v["archive"]['copyright'], "source": v["archive"]["source"], "cover": v["archive"]["cover"], "desc": v["archive"]["desc"], "desc_format_id": v["archive"]["desc_format_id"], "dynamic": v["archive"]["dynamic"], "tag": v["archive"]["tag"], "tid": v["archive"]["tid"], "title": new_title, "videos": [{ "desc": "", "filename": filename, "title": suffix }], # [{ # "desc": video['desc'], # "filename": video['filename'], # "title": video['title'] # } for video in v["videos"]], "handle_staff": False, 'bvid': v["archive"]["bvid"] } result = video_update_app(data, self.verify, self.account.access_token) print(f"{data['title']} updated: {result}") return result['bvid']
from bilibili_api import video from database import Database import time db = Database() videolist = db.get_video_list() for row in videolist: bvid = row['bvid'] vid = row['vid'] v = video.get_video_info(bvid=bvid) stat = v["stat"] data = { 'vid': vid, 'view': stat['view'], #播放数 'favorite': stat['favorite'], #收藏数 'danmaku': stat['danmaku'], #弹幕数 'reply': stat['reply'], #评论数 'coin': stat['coin'], #投币数 'share': stat['share'], #分享数 'now_rank': stat['now_rank'], #当前排名 'like': stat['like'] #点赞数 } db.save_video_data(data) time.sleep(0.5)