Python爬虫使用实例-mdrama

一个Python爬虫使用实例:主要用于下载指定的剧集音频。分别从网页和json文件中获取剧集的title和剧集中所存在音频的id,调用you-get,最后自动重命名下载文件夹为剧集名title。

目标网址:

https://www.missevan.com/mdrama/×××××

其中×××××为drama的id,例如28021

  • 从getdrama的json文件中获取drama列表中的id和name
  • 用you-get获取音乐1.使用pyautogui调用you-get ,2. 使用 os.system() 直接调用 you-get 命令行工具】
  • drama文件夹自动重命名为剧集名
  • 下载多个drama

一、获取资源

在这里插入图片描述
首先明确需求,需要获取音频的id和name分别作为data和title,查看源码,发现看不到:
在这里插入图片描述

可以从getdrama的json文件中获取id和name(不,用you-get的话只需要id)。
在这里插入图片描述
以28021为例,0-276,共277个music
在这里插入图片描述
小细节:听剧的时候一般是不会出现drama的,他一般是出现sound/player,点大标题可以跳转到drama,或者去源码查看(关于url)
在这里插入图片描述

二、发送请求

获取json文件

json_url = f'https://www.missevan.com/dramaapi/getdrama?drama_id={drama_id}'
# 将获取的 JSON 数据写入文件
with open('getdrama.json', 'w', encoding='utf-8') as f:f.write(response.text)

读取json文件

# 读取 getdrama.json 文件
with open('getdrama.json', 'r', encoding='utf-8') as f:content = f.read()

因为用的是you-get,需要提前切换到西文状态下,而文件夹名可能含有中文字符,所以在download之后才重命名为title。

# 下载音频文件
download_dir = 'D:/drama1/'
if not os.path.exists(download_dir):os.mkdir(download_dir)(省略部分代码....)download()
os.rename(download_dir, f'D:/{title}/')

三、数据解析

获取drama的id

drama_id = re.search(r'/mdrama/(\d+)', url).group(1)  # 提取 drama_id

获取drama的名称:

title = selector.css('.title-content::text').get().replace(' ','').replace('\n','')

获取drama中音频的id

# 匹配包含 "id" 和 "sound_id" 的 JSON 对象
pattern = r'\{"id":.*?\}'  # 正则表达式匹配模式
matches = re.findall(pattern, content)# 提取匹配的 JSON 对象中的所需字段
results = []for match in matches:try:data_dict = json.loads(match)sound_id = data_dict.get("sound_id")if sound_id:results.append({"name": data_dict.get("name"), "sound_id": sound_id})except json.JSONDecodeError:continue  # 忽略 JSON 解码错误# 将结果列表转换为 DataFrame
df = pd.DataFrame(results)

四、保存数据

you-get -o {download_dir} {url}

五、代码实现

1/ 单个剧集

单个drama可以自动改文件名 ,drama列表暂时不能

# 单个剧集mdrama 下载后自动改文件名
import os
import re
import json
import time
import requests
import parsel
import pyautogui
import pyperclip
import pandas as pdurl ='https://www.missevan.com/mdrama/23468'
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.139 Safari/537.36'}
drama_id = re.search(r'/mdrama/(\d+)', url).group(1)  # 提取 drama_id
json_url = f'https://www.missevan.com/dramaapi/getdrama?drama_id={drama_id}'
response = requests.get(json_url)
response1 = requests.get(url=url,headers=headers)
selector = parsel.Selector(response1.text)
title = selector.css('.title-content::text').get().replace(' ','').replace('\n','')
invalid_chars_pattern = r'[\/:*?"<>|]' # 定义需要替换的非法字符
title = re.sub(invalid_chars_pattern, '|', title) # 将非法字符替换为空格
print(title)
# 将获取的 JSON 数据写入文件
with open('getdrama.json', 'w', encoding='utf-8') as f:f.write(response.text)# 读取 getdrama.json 文件
with open('getdrama.json', 'r', encoding='utf-8') as f:content = f.read()# 匹配包含 "id" 和 "sound_id" 的 JSON 对象
pattern = r'\{"id":.*?\}'  # 正则表达式匹配模式
matches = re.findall(pattern, content)# 提取匹配的 JSON 对象中的所需字段
results = []
for match in matches:try:data_dict = json.loads(match)sound_id = data_dict.get("sound_id")if sound_id:results.append({"name": data_dict.get("name"), "sound_id": sound_id})except json.JSONDecodeError:continue  # 忽略 JSON 解码错误# 将结果列表转换为 DataFrame
df = pd.DataFrame(results)# 下载音频文件
download_dir = 'D:/drama1/'
if not os.path.exists(download_dir):os.mkdir(download_dir)# 打开命令提示符
pyautogui.hotkey("win", "r")
pyautogui.typewrite('cmd')
time.sleep(3)
pyautogui.press('enter')
time.sleep(3)def download():for sound_id in df['sound_id']:url = f"https://www.missevan.com/sound/player?id={sound_id}"pyautogui.typewrite(f'you-get -o {download_dir} {url}')# pyperclip.copy(url)# pyautogui.hotkey("ctrl", "v")pyautogui.press("enter")download()
os.rename(download_dir, f'D:/{title}/')

2/ 剧集列表

url是列表:

import os
import re
import json
import time
import requests
import parsel
import pyautogui
import pyperclip
import pandas as pd# 设置多个剧集的 URL 列表
urls = ['https://www.missevan.com/mdrama/23468','https://www.missevan.com/mdrama/1003',  # 添加更多剧集的 URL# 可以继续添加其他 URL
]
# 遍历每个 URL 进行处理
for url in urls:headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.139 Safari/537.36'}drama_id = re.search(r'/mdrama/(\d+)', url).group(1)  # 提取 drama_idjson_url = f'https://www.missevan.com/dramaapi/getdrama?drama_id={drama_id}'response = requests.get(json_url)response1 = requests.get(url=url, headers=headers)selector = parsel.Selector(response1.text)title = selector.css('.title-content::text').get().replace(' ', '').replace('\n', '')invalid_chars_pattern = r'[\/:*?"<>|]'  # 定义需要替换的非法字符title = re.sub(invalid_chars_pattern, '|', title)  # 将非法字符替换为空格print(title)# 将获取的 JSON 数据写入文件with open('getdrama.json', 'w', encoding='utf-8') as f:f.write(response.text)# 读取 getdrama.json 文件with open('getdrama.json', 'r', encoding='utf-8') as f:content = f.read()# 匹配包含 "id" 和 "sound_id" 的 JSON 对象pattern = r'\{"id":.*?\}'  # 正则表达式匹配模式matches = re.findall(pattern, content)# 提取匹配的 JSON 对象中的所需字段results = []for match in matches:try:data_dict = json.loads(match)sound_id = data_dict.get("sound_id")if sound_id:results.append({"name": data_dict.get("name"), "sound_id": sound_id})except json.JSONDecodeError:continue  # 忽略 JSON 解码错误# 将结果列表转换为 DataFramedf = pd.DataFrame(results)# 下载音频文件download_dir = f'D:/drama_{drama_id}/' # download_dir = 'D:/drama1/'if not os.path.exists(download_dir):os.mkdir(download_dir)# 打开命令提示符pyautogui.hotkey("win", "r")pyautogui.typewrite('cmd')time.sleep(3)pyautogui.press('enter')time.sleep(3)def download():for sound_id in df['sound_id']:url = f"https://www.missevan.com/sound/player?id={sound_id}"pyautogui.typewrite(f'you-get -o {download_dir} {url}')# pyperclip.copy(url)# pyautogui.hotkey("ctrl", "v")pyautogui.press("enter")download()

3/ 继续优化

优化代码:

  1. 删除 pyautogui 部分:使用 os.system() 直接调用 you-get 命令行工具,这消除了对图形界面的依赖并提高了代码的效率与稳定性。(原来使用的是pyautogui打开cmd命令提示符来使用you-get)
    在这里插入图片描述

  2. 批量重命名:在所有下载完成后,再统一进行批量重命名,添加了 download_directories 列表,用于存储每个 download_dir 和对应的 title。
    在这里插入图片描述
    出现了一个可能导致文件夹重命名失败的问题。title 变量在for循环中要在循环体内获取,每次URL处理时应动态产生,而不是在群体内静态不变。调整代码:
    在这里插入图片描述

4/ 最新代码

# 配合urls.txt使用
import os
import re
import json
import time
import parsel
import requests# 读取 URL 列表
url_file = 'urls.txt'  # 假设 URL 列表存储在这个文本文件中
with open(url_file, 'r', encoding='utf-8') as f:urls = [line.strip() for line in f if line.strip()]  # 逐行读取并去除空行headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.139 Safari/537.36'
}# 整体结果列表
total_results = []
download_directories = []  # 用于存储下载目录和标题的对应关系# 遍历每个 URL
for url in urls:drama_id = re.search(r'/mdrama/(\d+)', url).group(1)  # 提取 drama_idjson_url = f'https://www.missevan.com/dramaapi/getdrama?drama_id={drama_id}'response = requests.get(json_url)# 从响应获取标题response_text = response.text#pattern_title = r'"title":"(.*?)"'  # 假设标题在 JSON 中#title_match = re.search(pattern_title, response_text)#title = title_match.group(1).replace(' ', '').replace('\n', '') if title_match else f'drama_{drama_id}'selector = parsel.Selector(requests.get(url, headers=headers).text)title = selector.css('.title-content::text').get().replace(' ', '').replace('\n', '')invalid_chars_pattern = r'[\/:*?"<>|]'  # 定义需要替换的非法字符title = re.sub(invalid_chars_pattern, '|', title)  # 将非法字符替换为空格print(title)# 将获取的 JSON 数据写入文件json_filename = f'{drama_id}_getdrama.json'with open(json_filename, 'w', encoding='utf-8') as f:f.write(response_text)# 读取 JSON 文件with open(json_filename, 'r', encoding='utf-8') as f:content = f.read()# 匹配包含 "id" 和 "sound_id" 的 JSON 对象pattern = r'\{"id":.*?\}'  # 正则表达式匹配模式matches = re.findall(pattern, content)# 提取匹配的 JSON 对象中的所需字段results = []for match in matches:try:data_dict = json.loads(match)sound_id = data_dict.get("sound_id")if sound_id:results.append({"name": data_dict.get("name"), "sound_id": sound_id})except json.JSONDecodeError:continue  # 忽略 JSON 解码错误# 将结果添加到总结果列表total_results.extend(results)# 下载音频文件download_dir = f'D:/drama_{drama_id}/'download_directories.append((download_dir, title))  # 保存目录和标题if not os.path.exists(download_dir):os.makedirs(download_dir)# 下载音频文件(使用 you-get 命令行工具)for sound in results:sound_id = sound['sound_id']download_url = f"https://www.missevan.com/sound/player?id={sound_id}"os.system(f'you-get -o "{download_dir}" {download_url}')time.sleep(2)  # 添加延时,避免命令太快# 所有下载完成后,批量重命名文件夹
for download_dir, title in download_directories:target_dir = f'D:/{title}/'if not os.path.exists(target_dir):  # 检查重命名目标文件夹是否存在os.rename(download_dir, target_dir)print(f"文件夹 '{download_dir}' 已重命名为 '{target_dir}'")else:print(f"目标文件夹 '{target_dir}' 已存在,跳过重命名。")

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1555433.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

开源AI智能名片小程序源码:私域电商构建独特竞争力的新机遇

摘要&#xff1a;本文旨在探讨私域电商如何利用开源AI智能名片小程序源码构建独特竞争力。在强调独特性是通向成功的必要条件的基础上&#xff0c;分析开源AI智能名片小程序源码在私域电商发展独特性方面的作用及相关策略。 一、引言 在竞争激烈的商业环境中&#xff0c;让自己…

RTX4060安装nvidia显卡驱动

文章目录 nvidia drivers下载删除原有nvidia驱动安装nvidia驱动如果报错Unable to find the kernel source tree for the currently runningbuilding kernel modules解决方法 报错成功安装!!! nvidia drivers下载 https://www.nvidia.cn/geforce/drivers/#:~:textNVIDIA%20GeF…

Python从入门到高手5.1节-Python简单数据类型

目录 5.1.1 理解数据类型 5.1.2 Python中的数据类型 5.1.3 Python简单数据类型 5.1.4 特殊的空类型 5.1.5 Python变量的类型 5.1.6 广州又开始变热 5.1.1 理解数据类型 数据类型是根据数据本身的性质和特征来对数据进行分类&#xff0c;例如奇数与偶数就是一种数据类型。…

去噪扩散模型

Denoising Diffusion Probabilistic Models 图像扩散模型是一种生成模型&#xff0c;它基于概率扩散过程来生成新的图像。 核心步骤包括&#xff1a;&#xff08;1&#xff09;前向扩散过程&#xff1b;&#xff08;2&#xff09;逆向扩散过程 前向扩散过程&#xff08;正向过…

No.4 笔记 | 探索网络安全:揭开Web世界的隐秘防线

在这个数字时代&#xff0c;网络安全无处不在。了解Web安全的基本知识&#xff0c;不仅能保护我们自己&#xff0c;也能帮助我们在技术上更进一步。让我们一起深入探索Web安全的世界&#xff0c;掌握那些必备的安全知识&#xff01; 1. 客户端与WEB应用安全 前端漏洞&#xff1…

Spring Boot框架下的大学生就业招聘平台

5系统详细实现 5.1 用户模块的实现 5.1.1 求职信息管理 大学生就业招聘系统的用户可以管理自己的求职信息&#xff0c;可以对自己的求职信息添加修改删除操作。具体界面的展示如图5.1所示。 图5.1 求职信息管理界面 5.1.2 首页 用户登录可以在首页看到招聘信息展示也一些求职…

STM32中断——外部中断

目录 一、概述 二、外部中断&#xff08;Extern Interrupt简称EXTI&#xff09; 三、实例-对射式红外传感器 1、配置中断&#xff1a; 2 、完整代码 一、概述 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件(中断源)&#xff0c;使得CPU暂停当…

【图论】树剖(上):重链剖分

一、前置知识清单 深度优先搜索DFS 点我复习图的存储 复习链接敬请期待树状数组 点我复习 二、树剖简介 树剖&#xff08;树链剖分&#xff09;&#xff0c;是一种把树划分成链的算法&#xff0c;该算法分为重链剖分和长链剖分。 本文仅讨论重链剖分&#xff0c;长链剖分目前…

MySQL联合索引、索引下推Demo

1.联合索引 测试SQL语句如下&#xff1a;表test中共有4个字段(id, a, b, c)&#xff0c;id为主键 drop table test;#建表 create table test(id bigint primary key auto_increment,a int,b int,c int )#表中插入数据 insert into test(a, b, c) values(1,2,3),(2,3,4),(4,5,…

算法修炼之路之滑动窗口

目录 一&#xff1a;滑动窗口的认识及模板 二&#xff1a;LeetcodeOJ练习 1.第一题 2.第二题 3.第三题 4.第四题 5.第五题 6.第六题 7.第七题 一&#xff1a;滑动窗口的认识及模板 这里先通过一道题来引出滑动窗口 LeetCode 209 长度最小的子数组 画图分析&…

aws(学习笔记第一课) AWS CLI,创建ec2 server以及drawio进行aws画图

aws(学习笔记第一课) 使用AWS CLI 学习内容&#xff1a; 使用AWS CLI配置密钥对创建ec2 server使用drawio&#xff08;vscode插件&#xff09;进行AWS的画图 1. 使用AWS CLI 注册AWS账号 AWS是通用的云计算平台&#xff0c;可以提供ec2&#xff0c;vpc&#xff0c;SNS以及clo…

使用 Python 遍历文件夹

要解决这个问题&#xff0c;使用 Python 的标准库可以很好地完成。我们要做的是遍历目录树&#xff0c;找到所有的 text 文件&#xff0c;读取内容&#xff0c;处理空行和空格&#xff0c;并将处理后的内容合并到一个新的文件中。 整体思路&#xff1a; 遍历子目录&#xff1…

2.3MyBatis——插件机制

2.3MyBatis——插件机制 1.基本用法2.原理探究2.1加载过程2.2执行过程2.2.1 插件的执行点2.2.2 SQL执行的几个阶段2.2.3 如何梳理出执行流程 插件机制是一款优秀框架不可或缺的组成部分&#xff0c;比如spring、dubbo&#xff0c;还有我们要聊的Mybatis等等。所谓插件&#xff…

vSAN02:容错、存储策略、文件服务、快照与备份、iSCSI

目录 vSAN容错条带化存储策略1. 创建新策略2. 应用存储策略 vSAN文件服务文件服务快照与备份 vSAN iSCSI目标服务 vSAN容错 FTT&#xff1a;Fault to Tolerance 允许故障数 故障域&#xff1a;每一台vSAN主机是一个故障域 - 假设3台超融合&#xff08;3计算1存储&#xff09;&…

力扣 简单 110.平衡二叉树

文章目录 题目介绍解法 题目介绍 解法 平衡二叉树:任意节点的左子树和右子树的高度之差的绝对值不超过 1 //利用递归方法自顶向下判断以每个节点为根节点的左右子树的最大深度是否大于1 class Solution {public boolean isBalanced(TreeNode root) {if(root null){return tr…

基于Java的GeoTools对Shapefile文件属性信息深度解析

目录 前言 一、Shapefile的属性列表信息 1、属性表格信息 2、属性表格包含的要素 二、GeoTools对属性表格的解析 1、常规解析方法 2、基于dbf文件的属性信息读取 三、总结 前言 ESRI Shapefile&#xff08;shp&#xff09;&#xff0c;或简称shapefile&#xff0c;是美…

【Spring Boot React】Spring Boot和React教程 完整版

【Spring Boot & React】Spring Boot和React教程 在B站找到一个不错的SpringBoot和React的学习视频&#xff0c;作者是amigoscode 【Spring Boot & React】Spring Boot和React教程 2023年更新版【Spring Boot React】价值79.9美元&#xff0c;全栈开发&#xff0c;搭…

如何使用CMD命令启动应用程序(二)

说明&#xff1a;去年1024发布了一篇博客&#xff0c;介绍如何使用CMD命令启动应用程序&#xff0c;但实际情况&#xff0c;有些程序可能无法用配置环境变量的方式来启动&#xff0c;本文针对两种情况下的程序&#xff0c;如何使用CMD命令来启动&#xff0c;算是对上一篇博客的…

Qt操作主/从视图及XML——实例:汽车管理系统

目录 1. 主界面布局2.连接数据库3.主/从视图应用 1. 主界面布局 先创建一个QMainwindow&#xff0c;不带设计界面 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QGroupBox> #include <QTableView> #include <QListWidg…

鸿蒙harmonyos next flutter混合开发之开发plugin(获取操作系统版本号)

创建Plugin为my_plugin flutter create --org com.example --templateplugin --platformsandroid,ios,ohos my_plugin 创建Application为my_application flutter create --org com.example my_application flutter_application引用flutter_plugin&#xff0c;在pubspec.yam…