通过GitHub探索Python爬虫技术

news2024/12/27 13:40:46

1.检索爬取内容案例。

 2.找到最近更新的。(最新一般都可以直接运行)

 3.选择适合自己的项目,目前测试下面画红圈的是可行的。

4.方便大家查看就把代码粘贴出来了。

#图中画圈一代码
import requests
import os
import re


while True:
    music_id = input("请输入歌曲id或歌曲链接: ")
    if music_id.startswith("http"):
        music_id = re.search(r"id=(\d+)", music_id).group(1)
    get_lyric = requests.get(url="https://music.163.com/api/song/lyric", params={"id": music_id, "lv": 1, "kv": 1, "tv": -1}).json()
    print(get_lyric)
    if get_lyric.get("lrc").get("lyric") == "":
        print("该歌曲没有歌词")
    else:
        if not os.path.exists("./OutLyric"):
            os.makedirs("./OutLyric")
        with open(f"./OutLyric/{music_id}.lrc", "w", encoding="utf-8") as save_lyric:
            if get_lyric.get("tlyric").get("lyric") == "":
                save_lyric.write(get_lyric.get("lrc").get("lyric"))
            else:
                zh_cn_lyric = re.sub(r'\[[^0-9]*:[^0-9.]*]\n', '', get_lyric.get("tlyric").get("lyric"))
                save_lyric.write(f'{get_lyric.get("lrc").get("lyric")}\n{zh_cn_lyric}')
        print(f"下载成功,可将该文件重命名至与歌曲相同的名字使用,lrc文件保存至./OutLyric/{music_id}.lrc")
#图中画圈2代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests as rq
from requests import exceptions
from bs4 import BeautifulSoup as BS
import os
import re
import csv


SONG_NUM = 0


def getMusic(ID, path, num):
    cloud = 'http://music.163.com/song/media/outer/url?id='
    kv = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'}
    try:
        url = cloud+ID+'.mp3'
        tmp = rq.get(url, headers=kv)
        tmp.raise_for_status()
        print(num+"、歌曲正在下载...")
        with open(path, 'wb') as f:
            f.write(tmp.content)
        f.close()
        print(num+"、歌曲下载成功!")
    except exceptions.HTTPError as e:
        print(e)
    except Exception as e:
        print(e)


def getMusicText(ID, path, num):

    muTextUrl = 'http://music.163.com/api/song/lyric?id=' + ID + '&lv=1&kv=1&tv=-1'
    headers = {
        'Referer': 'https://music.163.com',
        'Host': 'music.163.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    }
    try:
        res = rq.get(muTextUrl, headers=headers)
        res.raise_for_status()
        false = False  # 解决eval报错 name 'false' is not defined
        true = True
        null = None
        lrc_dict = eval(res.text)  # 转换为dict字典
        lrc_dict = lrc_dict['lrc']
        music_lyric = lrc_dict['lyric']
        print(num+"、歌词正在下载...")
        with open(path, 'w', encoding="utf-8") as f:
            f.write(music_lyric)
        f.close()
        print(num+"、歌词下载成功!")
    except exceptions.HTTPError as e:
        print(e)
    except Exception as e:
        print(e)


def create_csv_head():
    headers = ['song_num', 'song_name', 'singer', 'song_duration']
    with open("./music/musicMsg.csv", "a", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=headers)
        head = {'song_num': '榜单序号', 'song_name': '歌曲名称',
                'singer': '歌手', 'song_duration': '歌曲时长'}
        writer.writerow(head)


def save_musicMsg(music_dict):
    headers = ['song_num', 'song_name', 'singer', 'song_duration']
    with open("./music/musicMsg.csv", "a", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=headers)
        writer.writerow(music_dict)


def split_Msg(msg):
    msg = msg.split('"')
    item = msg[1]
    return item


def getMusicMsg(ID):
    global SONG_NUM
    song_url = 'https://music.163.com/song?id=' + ID
    headers = {
        'Referer': 'https://music.163.com',
        'Host': 'music.163.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    }
    try:
        s = rq.session()
        res = s.get(song_url, headers=headers)
        soup = BS(res.content, 'lxml')
        # 获取歌手
        singer = str(soup.find('meta', {'property': 'og:music:artist'}))
        singer = split_Msg(singer)
        # 获取歌曲名
        song_name = str(soup.find('meta', {'property': 'og:title'}))
        song_name = split_Msg(song_name)
        # 获取歌曲时长
        song_duration = str(soup.find('meta', {'property': 'music:duration'}))
        song_duration = split_Msg(song_duration)
        m, s = divmod(int(song_duration), 60)
        song_duration = ("%02d:%02d" % (m, s))
        music_dict = {
            'song_num': SONG_NUM,
            'song_name': song_name,
            'singer': singer,
            'song_duration': song_duration
        }
        save_musicMsg(music_dict)
        # 歌曲名中/\\替换为空
        if '/' in song_name or '\\' in song_name or ':' in song_name:
            song_name = song_name.replace('/', '')
            song_name = song_name.replace('\\', '')
            song_name = song_name.replace(':', '')
        # 歌手名中/\\替换为&
        if '/' in singer or '\\' in singer or ':' in singer:
            singer = singer.replace('/', '&')
            singer = singer.replace('\\', '&')
            singer = singer.replace(':', '')
        dirName = singer+'-'+song_name
        print(dirName)

        return dirName
    except exceptions.HTTPError as e:
        print(e)
    except Exception as e:
        print(e)


def getMusicList():
    headers = {
        'Referer': 'https://music.163.com',
        'Host': 'music.163.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    }
    base_url = 'https://music.163.com/discover/toplist'
    s = rq.session()
    url = base_url
    response = s.get(url, headers=headers)
    soup = BS(response.content, "lxml")
    main = soup.find('ul', {'class': 'f-hide'})
    ls = main.find_all('a')
    songID_dic = {}  # key song_name ,value songID
    print('一共有'+str(len(ls))+'首歌')
    a = 1
    for music in ls:
        name = music.text
        ID = str(music['href'].replace('/song?id=', ''))
        name = name+'_'+str(a)
        a += 1
        songID_dic[name] = ID
        print("Name:{:30}\tID{:^10}".format(name, ID))
    print('一共有'+str(len(songID_dic))+'')
    return songID_dic


def main():
    global SONG_NUM
    songID_dic = getMusicList()
    rootDir = 'music'
    if os.path.exists(rootDir):
        print(rootDir+"文件夹已存在")
    else:
        os.mkdir(rootDir)
        print("创建文件夹"+rootDir)
    create_csv_head()
    for item in songID_dic:
        item_clear = item.split('_')[0]
        SONG_NUM += 1
        dirName = getMusicMsg(songID_dic[item])
        if dirName[-2:-1] == '.':
            dirName = dirName.replace('.', '·')
        musicDir = './'+rootDir+'/' + dirName
        if os.path.exists(musicDir):
            print(musicDir+"文件夹已存在")
        else:
            os.mkdir(musicDir)
        print("创建文件夹"+musicDir)
        if len(item_clear) > 75:
            item_clear = item_clear[:70]+'···'
        elif '.' in item_clear:
            item_clear = item_clear.replace('.', '·')
        print(item_clear, end="    \n")
        mp3_path = musicDir+'/'+item_clear+'.mp3'
        m4a_path = musicDir+'/'+item_clear+'.m4a'
        lyric_path = musicDir+'/'+item_clear+'.txt'
        num = str(SONG_NUM)
        print('='*50)
        getMusic(songID_dic[item], mp3_path, num)
        getMusic(songID_dic[item], m4a_path, num)
        print('*'*50)
        getMusicText(songID_dic[item], lyric_path, num)
        print('='*50)


if __name__ == '__main__':
    main()
    # getMusicList()
    # getMusicText("1994955842", "path")
    # getMusicMsg("1998931166")

 

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

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

相关文章

编译链接实战(22)C/C++代码覆盖率统计报告生成

文章目录 GCOV 工具简介gcov 使用lcov相关编译选项 GCOV 工具简介 gcov是一个测试代码覆盖率的工具,它是 gcc 自带的查看代码覆盖率的工具。 与GCC结合使用,可以分析您的程序以帮助创建更高效、运行更快的代码,并发现程序中未经测试的部分。…

Linux 之压缩与解压相关命令的基础用法

目录 1、zip 与 unzip 2、gzip 命令 3、tar 命令 1、zip 与 unzip 在桌面新建一个文件和文件夹用于测试 在 test 目录下有一个 1.txt 文件 我们使用 zip 命令对其压缩 用法: zip 自定义压缩包名 被压缩文件路径位置 zip myon.zip 1.txt 因为我们这里就是在 …

数据库管理-第157期 Oracle Vector DB AI-08(20240301)

数据库管理157期 2024-03-01 数据库管理-第157期 Oracle Vector DB & AI-08(20240301)1 创建示例向量2 查找最近向量3 基于向量簇组的最近向量查询总结 数据库管理-第157期 Oracle Vector DB & AI-08(20240301) 作者&…

多层感知器(神经网络)与激活函数

单个神经元(二分类) 多个神经元(多分类) 多层感知器 多层感知器,他是一种深度学习模型,通过多层神经元的连接和激活来解决非线性问题。 激活函数 激活函数的种类包括relu,sigmoid和tanh等 …

C 嵌入式系统设计模式 15:基本并发概念

本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之一…

GEE数据集——GLC_FCS30D - 全球 30 米土地覆被变化数据集(1985-2022 年)

GLC_FCS30D - 全球 30 米土地覆被变化数据集(1985-2022 年) 注 本数据集是正在提交的论文的一部分,因此没有引用和 DOI 信息。请在使用本数据集时注意这一点。 GLC_FCS30D 数据集是全球土地覆被监测领域的一项开创性进展,它以 30…

青少年CTF2024 #Round1 wp web

web EasyMD5 MD5碰撞,使用工具fastcoll生成内容不同但md5值相同的两个pdf文件上传即可获得flag; ./fastcoll_v1.0.0.5.exe -p 1.pdf -o 2.pdf 3.pdf # -p指定任意源文件,-o指定生成两个内容不同但md5值相同的目标文件 工具下载&#x…

【MySQL】复合查询(重点)-- 详解

一、基本查询练习回顾 1、查询工资高于 500 或岗位为 MANAGER 的雇员,同时还要满足他们的姓名首字母为大写的 J 2、按照部门号升序而雇员的工资降序排序 3、使用年薪进行降序排序 4、显示工资最高的员工的名字和工作岗位 5、显示工资高于平均工资的员工信息 6、显…

【AIGC】微笑的秘密花园:红玫瑰与少女的美好相遇

在这个迷人的画面中,我们目睹了一个迷人的时刻,女子则拥有一头柔顺亮丽的秀发,明亮的眼睛如同星河般璀璨,优雅而灵动,她的微笑如春日暖阳,温暖而又迷人。站在红玫瑰花瓣的惊人洪水中。 在一片湛蓝无云的晴…

100M服务器能同时容纳多少人访问

100M服务器的并发容纳人数会受到多种因素的影响,这些因素包括单个用户的平均访问流量大小、每个用户的平均访问页面数、并发用户比例、服务器和网络的流量利用率以及服务器自身的处理能力。 点击以下任一云产品链接,跳转后登录,自动享有所有…

精品SSM的选修课管理系统选课签到打卡

《[含文档PPT源码等]精品基于SSM的选修课管理系统设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功! 软件开发环境及开发工具: Java——涉及技术: 前端使用技术:HTM…

leetcode--接雨水(双指针法,动态规划,单调栈)

目录 方法一:双指针法 方法二:动态规划 方法三:单调栈 42. 接雨水 - 力扣(LeetCode) 黑色的是柱子,蓝色的是雨水,我们先来观察一下雨水的分布情况: 雨水落在凹槽之间,在一个凹槽的…

Laravel Octane 和 Swoole 协程的使用分析二

又仔细研究了下 Octane 源码和 Swoole 的文档,关于前几天 Laravel Octane 和 Swoole 协程的使用分析中的猜想,得到进一步验证: Swoole 的 HTTP Server 启动后会创建一个 master 进程和一个 manager 进程;master 进程又会创建多个…

持安科技孙维伯:零信任在攻防演练下的最佳实践|DISCConf 2023

近日,在2023数字身份安全技术大会上,持安科技联合创始人孙维伯应主办方的特别邀请,发表了主题为“零信任在攻防演练下的最佳实践”的演讲。 孙维伯在2023数字身份安全技术大会上发表演讲 以下为本次演讲实录: 我是持安科技的联合…

Leetcode 第 386 场周赛题解

Leetcode 第 386 场周赛题解 Leetcode 第 386 场周赛题解题目1:3046. 分割数组思路代码复杂度分析 题目2:3047. 求交集区域内的最大正方形面积思路代码复杂度分析 题目3:3048. 标记所有下标的最早秒数 I思路代码复杂度分析 题目4:…

网站添加pwa操作和配置manifest.json后,没有效果排查问题

pwa技术官网:https://web.dev/learn/pwa 应用清单manifest.json文件字段说明:https://web.dev/articles/add-manifest?hlzh-cn Web App Manifest:Web App Manifest | MDN 当网站添加了manifest.json文件后,也引入到html中了&a…

决定西弗吉尼亚州地区版图的关键历史事件

决定西弗吉尼亚州地区版图的关键历史事件: 1. 内部分裂与美国内战: - 在1861年美国内战爆发时,弗吉尼亚州作为南方邦联的一员宣布退出美利坚合众国。然而,弗吉尼亚州西部的一些县由于经济结构(主要是农业非依赖奴隶制…

小程序事件处理

事件处理 一个应用仅仅只有界面展示是不够的,还需要和用户做交互,例如:响应用户的点击、获取用户输入的值等等,在小程序里边,我们就通过编写 JS 脚本文件来处理用户的操作 1. 事件绑定和事件对象 小程序中绑定事件与…

学习:GPT-4技术报告2023.3

原文链接:GPT-4的 (openai.com) 摘要: 我们创建了 GPT-4,这是 OpenAI 在扩展深度学习方面的最新里程碑。GPT-4 是一个大型多模态模型(接受图像和文本输入,发出文本输出),虽然在许多现实世界场…

SpringBoot之Actuator的两种监控模式

SpringBoot之Actuator的两种监控模式 springboot提供了很多的检测端点(Endpoint),但是默认值开启了shutdown的Endpoint&#xff0c;其他默认都是关闭的,可根据需要自行开启 文章目录 SpringBoot之Actuator的两种监控模式1. pom.xml2. 监控模式1. HTTP2. JMX 1. pom.xml <de…