【全网独家有效附代码】一键爬取B站视频,一键去水印

我是智能取经人 2024-06-02 19:32:51

在这个信息爆炸的时代,自媒体人如雨后春笋般涌现,他们用独特的视角和创意,为观众带来新鲜的内容。然而,在这个过程中,他们经常面临一个棘手的问题:创意总有枯竭的时候,在其他平台上比如B站看到感兴趣的视频,如何高效地获取并进行二次加工,虽然市面上有很多类似的视频下载软件,但经常使用一段时间后就会被禁掉,今天,我将为大家揭秘如何使用Python,一键下载B站无水印视频,解决自媒体人的痛点!

故事背景

我的朋友小李是一名自媒体人,他经常在B站上寻找热点视频,希望将这些视频进行二次创作,发布到自己的媒体平台上。但问题来了,他发现市面上的视频下载软件要么下载速度慢,要么下载的视频带有水印,要么缴费用几天后被封禁。严重影响了视频的质量和二次创作的自由度。更糟糕的是,有时候他在平台上收藏的视频因为各种原因被UP主删除,导致他无法再次观看和使用。

Python自动化办公解决方案

针对小李的困境,我决定使用Python来自动化这一过程。Python作为一门强大的编程语言,拥有丰富的库和框架,可以轻松实现网络爬虫和视频处理的功能。

技术实现视音频爬取:使用Python的requests库和BeautifulSoup库,可以轻松获取B站视频页面的HTML内容,从而解析出视频的真实链接、音频的真实链接和、视频标题等信息。import requestsimport re # 正则表达式import pprintimport jsonfrom moviepy.editor import AudioFileClip, VideoFileClipfrom bs4 import BeautifulSoup as bsheaders = { # 防盗链 告诉服务器 我们请求的url网址是从哪里跳转过来的 'referer': 'https://www.bilibili.com/a', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}def send_request(url): response = requests.get(url=url, headers=headers) return responsedef get_video_data(html_data): """解析视频数据""" # 提取视频的标题 soup = bs(html_data, 'lxml') title = soup.find_all( name='h1', attrs={"class": "video-title special-text-indent"})[0].get_text() # print(title) # 提取视频对应的json数据 json_data = re.findall( '<script>window\.__playinfo__=(.*?)</script>', html_data)[0] # print(json_data) # json_data 字符串 json_data = json.loads(json_data) pprint.pprint(json_data) # 提取音频的url地址 audio_url = json_data['data']['dash']['audio'][0]['backupUrl'][0] print('解析到的音频地址:', audio_url) # 提取视频画面的url地址 video_url = json_data['data']['dash']['video'][0]['backupUrl'][0] print('解析到的视频地址:', video_url) video_data = [title, audio_url, video_url] return video_data视音频下载:通过解析到的url下载视频和音频的二进制文件到本地存储。这里下载到的视频是没有声音的def save_data(file_name, audio_url, video_url): # 请求数据 print('正在请求音频数据') audio_data = send_request(audio_url).content print('正在请求视频数据') video_data = send_request(video_url).content with open(file_name + '.mp3', mode='wb') as f: f.write(audio_data) print('正在保存音频数据') with open(file_name + '.mp4', mode='wb') as f: f.write(video_data) print('正在保存视频数据')视频合成:将获取到的视频和音频进行合成def merge_data(video_name): print('视频合成开始:', video_name) audioclip = AudioFileClip(video_name+'.mp3') videoclip = VideoFileClip(video_name+'.mp4') # 3.获取视频和音频的时长 video_time = videoclip.duration audio_time = audioclip.duration # 4.对视频或者音频进行裁剪 if video_time > audio_time: # 视频时长>音频时长,对视频进行截取 videoclip_new = videoclip.subclip(0, audio_time) audioclip_new = audioclip else: # 音频时长>视频时长,对音频进行截取 videoclip_new = videoclip audioclip_new = audioclip.subclip(0, video_time) # 5.视频中加入音频 video_with_new_audio = videoclip_new.set_audio(audioclip_new) # 6.写入到新的视频文件中 video_with_new_audio.write_videofile("output.mp4", codec='libx264', audio_codec='aac', temp_audiofile='temp-video.m4a', remove_temp=True ) print('视频合成结束:', video_name)url = 'https://www.bilibili.com/video/BV1ry411873J/?spm_id_from=333.999.0.0&vd_source=0665ce7d8c36aa587e1720c7def5640d'response = send_request(url)response.encoding = requests.utils.get_encodings_from_content(response.text)[0]html_data = response.textvideo_data = get_video_data(html_data)save_data(video_data[0], video_data[1], video_data[2])merge_data(video_data[0])去除水印:经常获取的视频有bilibili的水印,可以通过代码对视频进行编辑,从而去除视频中的水印。import cv2import numpy as npimport globfrom moviepy.editor import VideoFileClipimport osfrom tqdm import tqdm# 判断输入是否为视频def is_valid_video_file(file): try: with VideoFileClip(file) as video_clip: return True except Exception as e: print(f"Invalid video file: {file}, Error: {e}") return Falsedef get_first_valid_frame(video_clip, threshold=10, num_frames=10): total_frames = int(video_clip.fps * video_clip.duration) frame_indices = [int(i * total_frames / num_frames) for i in range(num_frames)] for idx in frame_indices: frame = video_clip.get_frame(idx / video_clip.fps) if frame.mean() > threshold: return frame return video_clip.get_frame(0)def select_roi_for_mask(video_clip): frame = get_first_valid_frame(video_clip) # 将视频帧调整为720p显示 display_height = 720 scale_factor = display_height / frame.shape[0] display_width = int(frame.shape[1] * scale_factor) display_frame = cv2.resize(frame, (display_width, display_height)) # instructions = "Select ROI and press SPACE or ENTER" # font = cv2.FONT_HERSHEY_SIMPLEX # cv2.putText(display_frame, instructions, (10, 30), font, 1, (255, 255, 255), 2, cv2.LINE_AA) r = cv2.selectROI(display_frame) cv2.destroyAllWindows() r_original = (int(r[0] / scale_factor), int(r[1] / scale_factor), int(r[2] / scale_factor), int(r[3] / scale_factor)) print("r_original: ", r_original) return r_original # return (18, 28, 230, 43)def detect_watermark_adaptive(frame, roi): roi_frame = frame[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2]] gray_frame = cv2.cvtColor(roi_frame, cv2.COLOR_BGR2GRAY) _, binary_frame = cv2.threshold( gray_frame, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) mask = np.zeros_like(frame[:, :, 0], dtype=np.uint8) mask[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2]] = 255 # binary_frame return maskdef generate_watermark_mask(video_clip, num_frames=10, min_frame_count=7): total_frames = int(video_clip.duration * video_clip.fps) frame_indices = [int(i * total_frames / num_frames) for i in range(num_frames)] frames = [video_clip.get_frame(idx / video_clip.fps) for idx in frame_indices] r_original = select_roi_for_mask(video_clip) masks = [detect_watermark_adaptive(frame, r_original) for frame in frames] final_mask = sum((mask == 255).astype(np.uint8) for mask in masks) # 根据像素点在至少min_frame_count张以上的帧中的出现来生成最终的遮罩 final_mask = np.where(final_mask >= min_frame_count, 255, 0).astype(np.uint8) kernel = np.ones((5, 5), np.uint8) return cv2.dilate(final_mask, kernel)def process_video(video_clip, output_path, apply_mask_func): total_frames = int(video_clip.duration * video_clip.fps) progress_bar = tqdm(total=total_frames, desc="Processing Frames", unit="frames") # num=0 def process_frame(frame): result = apply_mask_func(frame) progress_bar.update(1000) # global num # num += 1 # result.save('0%5d.png' % num) return result processed_video = video_clip.fl_image(process_frame, apply_to=["each"]) processed_video.write_videofile(f"{output_path}.mp4", codec="libx264")if __name__ == "__main__": video = "output.mp4" output_video_path = "output_nowatermask.mp4" if is_valid_video_file(video): video_clip = VideoFileClip(video) watermark_mask = generate_watermark_mask(video_clip) def mask_func(frame): return cv2.inpaint( frame, watermark_mask, 3, cv2.INPAINT_NS) video_name = os.path.basename(video) process_video(video_clip, output_video_path, mask_func) print(f"Successfully processed {video_name}")去除水印在需要在运行以上程序后,利用鼠标框选出水印的位置后按Enter进行程序进一步运行自动化脚本:将上述步骤封装成一个Python脚本,用户只需输入B站视频链接,即可自动完成下载和去水印的过程。效果展示

爬取视频音频并合成有声音的视频

去水印效果

水印去除

结语

Python自动化办公不仅仅是一个技术手段,它更是一种提高工作效率、释放创造力的工具。在这个自媒体竞争激烈的时代,每一个能够提升效率的工具都值得我们去探索和利用。希望我的分享能够帮助到更多的自媒体人,让我们一起用技术改变工作,用创意点亮生活!

想要获取完整代码可关注微信公众号数海丹心,私信“B站"获取

至此小编已经将微信公众号、抖音和哔哩哔哩三大流量平台的爬虫全部分享出来了,感兴趣的朋友可自行获取

【全网独家有效】一键爬取微信公众号所有文章,原样保留格式成PDF!

几行python代码:实现抖音视频批量下载,短视频搬用和二次创作的最大福音

0 阅读:0

我是智能取经人

简介:感谢大家的关注