python爬虫-个人记录

此文章仅作为个人学习记录,其他人可用作参考,仅供学习技术交流

针对的网站嘛,就是看动漫的那个网站,懂得都懂,不懂的就算了

1.使用的库

import json
import pprint  # 查看数据
import subprocess
import requests
import re  # 正则表达式

2.发送请求

def get_response(html_url):
    """
    发送请求
    :param html_url:请求的url地址
    :return:返回请求服务器返回的响应数据
    """
    # 在发送请求之前,需要进行伪装headers请求头
    # user-agent 浏览器基本标识 用户代理 基本伪装 反反爬的手段
    # 出现 403 加防盗链 referer
    headers = {
        'referer': 'xxx',  # 加防盗链 referer        此处xxx为请求头中的信息可去请求头中查看
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'
    }
    response = requests.get(url=html_url, headers=headers)  # 请求代码
    # <Response [200]>  对象response响应对象  200 状态码 表示请求成功
    # 404 >>> 你所拨打的电话是空号 >>> 网址出错
    # 403 >>> 你所拨打的电话不在服务区 >>> 你没有访问权限
    return response

如chrome浏览器在headers中的referer和user-agent可以在请求头中找到

3.获取视频标题、音频url地址、视频画面url地址

def get_video_info(html_url):
    """
    获取视频标题 / 音频url地址 / 视频画面url地址
    :param html_url: 视频的详情页
    :return: 视频标题 / 音频url地址 / 视频画面url地址
    """
    response = get_response(html_url=html_url)
    # response.text 获取响应体的文本数据
    # print(response.text)
    # 只要你可以看到数据 就可以下载 进行批量下载
    # 解析数据 提取视频标题 re正则表达式 css选择器 xpath(解析方式) bs4 parsel lxml(解析模块) jsonpath 主要提取json数据
    # 通过re正则表达式里面findall方法提取数据内容 ‘返回都是列表数据类型[0] 列表 索引取值
    # 想要的内容用括号括起来 .*? 可以匹配任意字符(除了换行符以外\n)  从response.text 里面查找数据
    title = re.findall('<h1 id="video-title" title="(.*?)" class="video-title">', response.text)[0]  # 标题
    html_data = re.findall('<script>window.__playinfo__=(.*?)</script>', response.text)[0]  # 提取播放信息
    # html_data 是什么样的数据类型 <class 'str'>
    # 为了更加方便提取数据, 可以字符串数据 转换成 字段数据类型
    # print(title)
    # print(html_data)
    # pprint.pprint(html_data)
    # print(type(html_data))
    json_data = json.loads(html_data)
    # 根据冒号左边的内容,提取冒号右边的内容 键值对取值
    audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
    video_url = json_data['data']['dash']['video'][0]['baseUrl']
    video_info = [title, audio_url, video_url]
    # pprint.pprint(json_data)
    # print(audio_url)
    # print(video_url)
    return video_info

4.保存数据(音频数据、视频数据)

def save(title, audio_url, video_url):
    """
    保存数据函数
    :param title:视频标题
    :param audio_url: 音频url
    :param video_url: 视频画面url
    :return:
    """
    # 保存音频 视频数据 获取二进制数据内容
    # 使用正则表达式将标题当中的所有标点符号替换为空
    title = re.sub('\W+', '', title).replace("_", '')
    audio_content = get_response(html_url=audio_url).content
    video_content = get_response(html_url=video_url).content
    with open(title + '.mp3', mode='wb') as f:
        f.write(audio_content)
    with open(title + '.mp4', mode='wb') as f:
        f.write(video_content)
        print(title, '保存成功~~~')

5.使用主函数调用

def main(bv_id):
    """
    主函数
    :param bv_id: bv号
    :return:
    """
    url = f'https://xxx/video/{bv_id}'  # 此处xxx为链接什么链接也就不用多说啦
    video_info = get_video_info(url)
    save(video_info[0], video_info[1], video_info[2])
   

keyword = input('请输入你要下载的视频BV号:')
main(keyword)

到此可以已经可以下载出单独的纯音频和纯视频

输入后面的下载视频的bv号即可

6.下载并且配置ffpeg环境变量

接下来就是合成音频和视频,需要下载ffmpeg,然后给ffmpeg配置环境变量,可以去官网下载

 下载好之后可以解压到自己喜欢的路径,然后配置环境变量   

此电脑->属性->高级系统设置->环境变量->系统变量->path中添加ffmpeg的bin目录

D:\ffmpeg\ffmpeg-5.0-essentials_build\bin

然后进入cmd输入ffmpeg -version查看是否配置完成

这样就算完成了

7.数据合并

加上这个函数就可以调用ffmpeg进行合成数据

def merge_data(video_name):
    """数据合并"""
    # 使用正则表达式将标题当中的所有标点符号替换为空,防止执行ffmpeg合并视频和音频时输出视频失败
    video_name = re.sub('\W+', '', video_name).replace("_", '')
    print('视频合成开始:', video_name)
    cmd = f"D:/ffmpeg/ffmpeg-5.0-essentials_build/bin/ffmpeg -i {video_name}.mp4 -i {video_name}.mp3 -c:v copy -c:a aac -strict experimental {video_name}out.mp4"
    # print(cmd)
    subprocess.run(cmd, shell=True)
    print('视频合成结束:', video_name)

 此时在主函数也有需要调用这个函数

更改后的main函数

def main(bv_id):
    """
    主函数
    :param bv_id: bv号
    :return:
    """
    url = f'https://xxx/video/{bv_id}'  # 此处xxx为链接什么链接不准说
    video_info = get_video_info(url)
    save(video_info[0], video_info[1], video_info[2])
    #调用数据合并
    merge_data(video_info[0])

8.踩过的坑

 最后说一下我自己踩过的坑,当然以上代码都是完善过的,所以我使用没什么问题

到合并那块调用ffpeg就出了很多问题

第一个问题最主要的就是我明明配置了环境变量也没写错,就是无法合并

我出现的问题就是这样,百度了好久都没有结果,之后找到的结果是需要定位到精确的路径使用

cmd = f"D:/ffmpeg/ffmpeg-5.0-essentials_build/bin/ffmpeg -i {video_name}.mp4 -i {video_name}.mp3 -c:v copy -c:a aac -strict experimental {video_name}out.mp4"

也就是这样在命令前加上路径

第二个问题就是命令行无法针对空格识别的问题,因为很多视频标题里面或多或少都有空格,这样会影响cmd运行,他是针对之前下载的两个文件名称合并,如果两个文件名中有空格,cmd就不好识别到文件路径,所以在网上找到的解决方法就是把符号啥的替换为空

    # 使用正则表达式将标题当中的所有标点符号替换为空
    title = re.sub('\W+', '', title).replace("_", '')
    # 使用正则表达式将标题当中的所有标点符号替换为空,防止执行ffmpeg合并视频和音频时输出视频失败
    video_name = re.sub('\W+', '', video_name).replace("_", '')

这样名称就不会影响结果输出

9.完整代码

import json
import pprint  # 查看数据
import subprocess
import requests
import re  # 正则表达式


def get_response(html_url):
    """
    发送请求
    :param html_url:请求的url地址
    :return:返回请求服务器返回的响应数据
    """
    # 在发送请求之前,需要进行伪装headers请求头
    # user-agent 浏览器基本标识 用户代理 基本伪装 反反爬的手段
    # 出现 403 加防盗链 referer
    headers = {
        'referer': 'xxx',  # 加防盗链 referer       此处的xxx去请求头里查看
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'
    }
    response = requests.get(url=html_url, headers=headers)  # 请求代码
    return response


def get_video_info(html_url):
    """
    获取视频标题 / 音频url地址 / 视频画面url地址
    :param html_url: 视频的详情页
    :return: 视频标题 / 音频url地址 / 视频画面url地址
    """
    response = get_response(html_url=html_url)
    # response.text 获取响应体的文本数据
    # print(response.text)
    # 只要你可以看到数据 就可以下载 进行批量下载
    # 解析数据 提取视频标题 re正则表达式 css选择器 xpath(解析方式) bs4 parsel lxml(解析模块) jsonpath 主要提取json数据
    # 通过re正则表达式里面findall方法提取数据内容 ‘返回都是列表数据类型[0] 列表 索引取值
    # 想要的内容用括号括起来 .*? 可以匹配任意字符(除了换行符以外\n)  从response.text 里面查找数据
    title = re.findall('<h1 id="video-title" title="(.*?)" class="video-title">', response.text)[0]  # 标题
    html_data = re.findall('<script>window.__playinfo__=(.*?)</script>', response.text)[0]  # 提取播放信息
    # html_data 是什么样的数据类型 <class 'str'>
    # 为了更加方便提取数据, 可以字符串数据 转换成 字段数据类型
    # print(title)
    # print(html_data)
    # pprint.pprint(html_data)
    # print(type(html_data))
    json_data = json.loads(html_data)
    # 根据冒号左边的内容,提取冒号右边的内容 键值对取值
    audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
    video_url = json_data['data']['dash']['video'][0]['baseUrl']
    video_info = [title, audio_url, video_url]
    # pprint.pprint(json_data)
    # print(audio_url)
    # print(video_url)
    return video_info


def save(title, audio_url, video_url):
    """
    保存数据函数
    :param title:视频标题
    :param audio_url: 音频url
    :param video_url: 视频画面url
    :return:
    """
    # 保存音频 视频数据 获取二进制数据内容
    # 使用正则表达式将标题当中的所有标点符号替换为空
    title = re.sub('\W+', '', title).replace("_", '')
    audio_content = get_response(html_url=audio_url).content
    video_content = get_response(html_url=video_url).content
    with open(title + '.mp3', mode='wb') as f:
        f.write(audio_content)
    with open(title + '.mp4', mode='wb') as f:
        f.write(video_content)
        print(title, '保存成功~~~')


def merge_data(video_name):
    """数据合并"""
    # 使用正则表达式将标题当中的所有标点符号替换为空,防止执行ffmpeg合并视频和音频时输出视频失败
    video_name = re.sub('\W+', '', video_name).replace("_", '')
    print('视频合成开始:', video_name)
    cmd = f"D:/ffmpeg/ffmpeg-5.0-essentials_build/bin/ffmpeg -i {video_name}.mp4 -i {video_name}.mp3 -c:v copy -c:a aac -strict experimental {video_name}out.mp4"
    # print(cmd)
    subprocess.run(cmd, shell=True)
    print('视频合成结束:', video_name)


def main(bv_id):
    """
    主函数
    :param bv_id: bv号
    :return:
    """
    url = f'https://xxx/video/{bv_id}'  # 此处的xxx为链接什么链接不能写
    video_info = get_video_info(url)
    save(video_info[0], video_info[1], video_info[2])
    #调用数据合并
    merge_data(video_info[0])


keyword = input('请输入你要下载的视频BV号:')
main(keyword)

# response = get_response(html_url=url)
# response.text 获取响应体的文本数据
# print(response.text)

此文章仅供学习,也作为个人记录,如果各位大佬有什么问题可以相互讨论。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值