【python爬虫】GUI界面爬虫爬取音乐

该篇文章编写的GUI界面爬虫,代码复制下来即可使用;如要查看爬虫分析原理请转到 python爬虫爬取音乐-JS逆向爬虫

from tkinter import Tk, Label, scrolledtext, Entry, Button, END, filedialog, messagebox, FLAT

import requests,time,hashlib


class UI:
    #参数定义项
    searchContent = ""
    folderPath = ""
    pageNo = 1
    pageSize = 20
    musicTotal = 0
    downloadMusicList = {}
    searchUrl = "https://music.91q.com/v1/search"
    musicInfoUrl = "https://music.91q.com/v1/song/tracklink"
    secret = "0b50b02fd0d73a9c4c8c3a781c30845f"
    appid = 16073360

    def __init__(self):
        self.main()

    #tkinter容器主运行程序
    def main(self):
        global root
        root = Tk()
        self.args()
        self.lable()
        self.text()
        self.button()
        root.mainloop()
    
    #tkinter界面配置
    def args(self):
        root.title("music download")
        root.geometry("1200x700+350+200")
        root.resizable(width=False, height=False)
        root.configure(bg="#faebd7")
    
    #界面标签
    def lable(self):
        lab1 = Label(root, text="请先选择保存路径后再下载!!!", font=("宋体", 15), bg="#faebd7", fg="red")
        lab1.place(x="500", y="5")
        lab2 = Label(root, text="请输入歌曲前方序号:", font=("宋体", 12), bg="#faebd7", fg="blue")
        lab2.place(x="480", y="105")
    
    #文本框
    def text(self):
        global musicListText, msgOutputText, searchText, downloadNumText, pageNoText
        musicListText = scrolledtext.ScrolledText(root, font=("宋体", 15), relief=FLAT, fg="green")
        musicListText.place(height="500", width="450", x="100", y="150")
        msgOutputText = scrolledtext.ScrolledText(root, font=("宋体", 15), relief=FLAT, fg="green")
        msgOutputText.place(height="500", width="450", x="650", y="150")
        searchText = Entry(root, font=("宋体", 15), relief=FLAT, fg="green")
        searchText.place(height="30", width="300", x="400", y="50")
        downloadNumText = Entry(root, font=("宋体", 15), relief=FLAT, fg="green")
        downloadNumText.place(height="30", width="60", x="640", y="100")
        pageNoText = Entry(root, font=("宋体", 15), relief=FLAT, fg="black", bg="#faebd7")
        pageNoText.place(height="30", width="50", x="845", y="100")
    
    #按钮
    def button(self):
        global searchButton, choosePathButton, downloadAllButton, downloadSingeButton, lastPageButton, nextPageButton, deleteMegButton
        searchButton = Button(root, text="搜索", bg="orchid" ,command =lambda : self.get_music())
        searchButton.place(height="30", width="40", x="710", y="50")
        choosePathButton = Button(root, text="保存路径", bg="orchid",command =lambda : self.path())
        choosePathButton.place(height="30", width="60", x="760", y="50")
        downloadAllButton = Button(root, text="全部下载", bg="orchid" , command = lambda: self.downloadMusic("all"))
        downloadAllButton.place(height="30", width="60", x="830", y="50")
        downloadSingeButton = Button(root, text="单曲下载", bg="orchid",command = lambda: self.downloadMusic("singe"))
        downloadSingeButton.place(height="30", width="60", x="710", y="100")
        lastPageButton = Button(root, text="上一页", bg="orchid", command=lambda: self.last_page())
        lastPageButton.place(height="30", width="60", x="780", y="100")
        nextPageButton = Button(root, text="下一页", bg="orchid", command=lambda : self.next_page())
        nextPageButton.place(height="30", width="60", x="900", y="100")
        deleteMegButton = Button(root, text="清除信息", bg="orchid", command=self.delete_message)
        deleteMegButton.place(height="30", width="60", x="900", y="50")
    
    #禁用或启用按钮
    def disableButton(self,state):
        if state == "disabled":
            searchButton.configure(state="disabled")
            choosePathButton.configure(state="disabled")
            downloadAllButton.configure(state="disabled")
            downloadSingeButton.configure(state="disabled")
            lastPageButton.configure(state="disabled")
            nextPageButton.configure(state="disabled")
            deleteMegButton.configure(state="disabled")
        else:
            searchButton.configure(state="normal")
            choosePathButton.configure(state="normal")
            downloadAllButton.configure(state="normal")
            downloadSingeButton.configure(state="normal")
            lastPageButton.configure(state="normal")
            nextPageButton.configure(state="normal")
            deleteMegButton.configure(state="normal")



    # 获取搜索的音乐
    def get_music(self):
        self.pageNo = 1
        self.searchContent = ""
        self.searchContent = searchText.get()
        msgOutputText.delete(0.0, END)
        self.searchMusic()


    # 保存路径
    def path(self):
        self.folderPath = ""
        self.folderPath = filedialog.askdirectory()
        msgOutputText.insert(0.0, " 音乐已保存在: " + self.folderPath + "\n")

    # 提示框
    def alert(self):
        messagebox.showinfo(title="提示", message="请选择保存路径后在下载!!!")
        self.path()


    #  清除信息
    def delete_message(self):
        msgOutputText.delete(0.0, END)


    # 下一页
    def next_page(self):
        if self.pageNo <= self.musicTotal/self.pageSize:
            self.pageNo += 1
            self.searchMusic()



    # 上一页
    def last_page(self):
        if self.pageNo > 1:
            self.pageNo -= 1
            self.searchMusic()



    #md5加密
    def md5Encode(self,str):
        md5 = hashlib.md5()
        md5.update(str.encode('utf-8'))
        return md5.hexdigest()

    #获取时间戳
    def getTimeStamp(self):
        return int(time.time())

    #音乐搜索函数
    def searchMusic(self):
        self.disableButton("disabled")
        timeStamp = self.getTimeStamp()
        args = {
            "sign": "",
            "word": self.searchContent,
            "type": 1,
            "pageNo": self.pageNo,
            "pageSize": self.pageSize,
            "appid": self.appid,
            "timestamp": timeStamp
        }
        signParam = "appid={0}&pageNo={1}&pageSize={2}&timestamp={3}&type=1&word={4}{5}".format(self.appid,self.pageNo,self.pageSize,timeStamp,self.searchContent,self.secret)
        args["sign"] = self.md5Encode(signParam)
        res = requests.get(url=self.searchUrl,params=args).json()
        self.musicTotal = res["data"]["total"]
        musicId = 1 #音乐id,用于单曲下载是使用该id找到相关音乐
        musicListText.delete(0.0,END) #清空音乐列表
        pageNoText.delete(0,END) #删除分页序号
        pageNoText.insert(0,"第{}页".format(self.pageNo)) #插入分页序号
        self.downloadMusicList.clear() #清空待下载音乐列表;每次分页后都会清空
        if len(res["data"]["typeTrack"]) !=0:
            for item in res["data"]["typeTrack"]:
                info = "{}. {}  -- {}\n".format(musicId,item["title"],item["artist"][0]["name"])
                self.getMusicUrl(item,musicId,item["title"])
                musicListText.insert(END,info)
                musicListText.update()
                musicId += 1
        else:
            messagebox.showinfo(title="提示", message="暂无搜索到相关歌曲!")
        self.disableButton("normal")


    # 获取音乐详细信息
    def getMusicInfo(self,TSID):
        timeStamp = self.getTimeStamp()
        args = {
            "sign": "",
            "appid": self.appid,
            "TSID": TSID,
            "timestamp": timeStamp
        }
        signParam = "TSID={0}&appid={1}&timestamp={2}{3}".format(TSID,self.appid,timeStamp,self.secret)
        args["sign"] = self.md5Encode(signParam) 
        res = requests.get(url=self.musicInfoUrl,params=args)
        return res.json()


    # 处理音乐详细信息后获得音乐数据链接
    def getMusicUrl(self,Info,count,title):
        global musicInfo
        try:
            musicInfo = self.getMusicInfo(Info["assetId"])
            self.downloadMusicList[count] = {"url":musicInfo["data"]["path"],"artist":title}
        except: #处理不同字段下的数据
            self.downloadMusicList[count] = {"url":musicInfo["data"]["trail_audio_info"]["path"],"artist":title}
        time.sleep(0.1) #进行爬取时最好加上休眠时间,有些请求做了反爬处理,如果同一ip在1s内处理达到阈值会封ip

    #下载音乐
    def downloadMusic(self,type):
        downloadNum = downloadNumText.get()
        if type == "all":
            for key,value in self.downloadMusicList.items():
                self.download(value["url"],value["artist"])
        else:
            if downloadNum == "":
                messagebox.showinfo(title="提示", message="请输入下载序号!!!")
            else:
                data = self.downloadMusicList.get(int(downloadNum))
                self.download(data["url"], data["artist"])



    #下载
    def download(self,url,title):
        if self.folderPath == "":
            self.alert()
        else:
            path = "{0}\{1}.mp3".format(self.folderPath,title)
            mess=requests.get(url)
            with open(path,'wb') as f:
                f.write(mess.content)
            msgOutputText.insert(END,title + 5*" " + "已下载成功!" + "\n")
            msgOutputText.update()


if __name__ == "__main__":
    UI()



Python中的爬虫GUI登录界面通常涉及到GUI库如Tkinter、PyQt或wxPython等,结合Web浏览器自动化工具如Selenium或Requests-HTML来模拟用户交互。下面是一个简单的步骤概述: 1. **安装必要的库**:首先需要安装`python-tk`(Tkinter的基础包),以及如`selenium`(用于控制浏览器)、`webdriver_manager`(管理浏览器驱动)`pyautogui`(处理图形用户界面操作)。 ```bash pip install tk selenium webdriver_manager pyautogui ``` 2. **创建登录界面**:使用Tkinter或其他库构建一个包含用户名密码输入框,以及登录按钮的简单窗口。当用户填写信息并点击登录后,可以获取这些值。 ```python import tkinter as tk def login(): username = entry_username.get() password = entry_password.get() # 进行登录逻辑... root = tk.Tk() entry_username = tk.Entry(root) entry_password = tk.Entry(root, show="*") login_button = tk.Button(root, text="Login", command=login) # ...其他布局设置... ``` 3. **模拟登录过程**:在`login`函数中,利用Selenium打开网页,填充用户名密码,然后提交表单。 ```python from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager driver = webdriver.Chrome(ChromeDriverManager().install()) driver.get("http://example.com/login") # 替换为你需要登录的网站地址 username_field = driver.find_element_by_name("username") # 查找输入框 password_field = driver.find_element_by_name("password") username_field.send_keys(username) password_field.send_keys(password) submit_button = driver.find_element_by_xpath("//button[@type='submit']") submit_button.click() # 登录成功后的处理... ``` 4. **错误处理退出**:确保处理可能出现的各种网络请求异常,并在登录完成后关闭浏览器。 完成上述步骤后,你就有了一个基本的Python GUI登录界面,用于爬取需要登录验证的网站内容。需要注意的是,遵守网站的robots.txt协议使用条款,在合法范围内进行爬取
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二九筒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值