b站爬虫(仅供学习)

先上全部代码,过程在注释里很详细,可能会出现的问题解决方法在文章后面有链接 

import os
import re
import requests
from bs4 import BeautifulSoup

# 可以使用自己的user-agent
headers_1 = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.54"
}

# 可以随意填几个存在的,无需使用自身ip
# 多ip轮换,防止请求被拒绝
proxy_list = [
    "http://173.18.243.163:port",
    "http://173.18.213.54:port",
    "http://173.0.0.1:9125:port",
    "http://173.0.0.1:9187:port",
    "http://173.0.0.1:9137:port"
    "http://173.17.0.1:9137:port"
]

# b站查询视频的关键词
# eg.陈翔六点半
target = input("请输入target值: ")

# 所用代理ip序号
proxy_index = 0
# 爬取数量
count = 0
# html中会提取两个重复的url,此标记用于每隔一个下载一个视频
del_rep = 0

# 用于自动创建该路径的路径
download_folder_init = f"e://B站视频/{target}/temp/"
# 下载路径
download_folder = f"e://B站视频/{target}/"
# 如果路径不存在则自动创建
if not os.path.exists(download_folder_init):
    os.makedirs(download_folder_init)
    print(f"文件夹 '{download_folder_init}' 创建成功!")

# b站的搜索以页数分类
for pagenum in range(1, 50, 1):
    # 页数为第一页和后面的网址结构有所不同
    if pagenum == 1:
        res = requests.get(f"https://www.bilibili.com/search?keyword={target}", headers=headers_1,
                           proxies={"http": proxy_list[proxy_index]})
    else:
        res = requests.get(f"https://www.bilibili.com/search?keyword={target}&page={pagenum}&o={pagenum * 30}",
                           headers=headers_1,
                           proxies={"http": proxy_list[proxy_index]})
    # 200为网络申请成功的返回编码
    if res.status_code == 200:
        print("连接正常~")
    # 提取返回的html源码
    html_1 = res.text
    # 用美化库处理html内容
    html_2 = BeautifulSoup(html_1, "html.parser")
    # 筛选需要的标签
    html_3 = html_2.findAll("a")

    # 遍历筛选内容
    for html_ in html_3:
        # 筛选标签中的内容
        if "href" in html_.attrs :
            video_url_init = html_["href"]
            # 如果存在视频标签
            if "video" in video_url_init:
                # 不重复标记标记
                del_rep += 1
                # 当为奇数时进入,排除重复url
                if del_rep % 2 == 1:
                    video_url = "https:" + video_url_init
                    print(video_url)

                    headers = {
                        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.54",
                        "referer": video_url
                    }

                    # 申请对应视频url的html内容
                    res = requests.get(video_url, headers=headers, proxies={"http": proxy_list[proxy_index]})
                    response = res.content.decode()
                    # 提取标题
                    video_name = re.findall(f'name="title" content="(.*?)_哔哩哔哩_bilibili">', response)

                    # 处理标题提取失败的情况防止中断
                    if len(video_name) > 0:
                        pass
                    else:
                        video_name = [f"_no_get_title"]

                    print(f'{count}.《{video_name[0]}》:下载中---请稍等---')
                    # 正则表达式筛选音频的url
                    audio_link = re.findall(r'"audio":\[{"id":\d+,"baseUrl":"(.*?)"', response)
                    # 正则表达式筛选视频(无声音)的url
                    video_link = re.findall(r'video":\[{"id":\d+,"baseUrl":"(.*?)"', response)
                    # 申请音频二进制内容
                    audio = requests.get(url=audio_link[0], headers=headers,
                                         proxies={"http": proxy_list[proxy_index]}).content
                    # 以二进制下载到本地设定文件夹内
                    with open(f'{download_folder}temp/{count}_audio.mp3', 'wb') as f:
                        f.write(audio)
                        f.close()
                    # 跟换代理ip防止服务器拒绝请求
                    proxy_index += 1
                    if proxy_index == len(proxy_list):
                        proxy_index = 0
                    # 申请视频二进制内容
                    video = requests.get(video_link[0], headers=headers,
                                         proxies={"http": proxy_list[proxy_index]}).content
                    # 以二进制下载到本地设定文件夹内
                    with open(f'{download_folder}temp/{count}_video.mp4', 'wb') as f:
                        f.write(video)
                        f.close()
                    # 使用os模块向控制台发出请求将temp中的视频和音频合成放在设定路径内
                    os.system(f'ffmpeg -i "{download_folder}temp/{count}_video.mp4" -i "{download_folder}temp/{count}_audio.mp3" -c copy "{download_folder}{count}_{video_name[0]}.mp4"')
                    # 合成以后删除temp文件夹内的视频金和音频文件
                    os.remove(f"{download_folder}temp/{count}_video.mp4")
                    os.remove(f"{download_folder}temp/{count}_audio.mp3")
                    # 计数
                    count += 1

模块的下载:python模块的下载-CSDN博客

 查询user-agent:查询user-agent-CSDN博客

ffmpeg的安装:ffmpeg的安装-CSDN博客

ffmped‘�����ڲ����ⲿ���Ҳ���ǿ����еij��� ���������ļ���: ‘ffmped‘ �����ڲ����ⲿ���Ҳ���ǿ����еij��� ���������ļ���-CSDN博客

 

 

你可能感兴趣的:(爬虫,笔记,ffmpeg,爬虫,学习,ffmpeg,经验分享,笔记)