ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Python 实战项目:网页 JS 数据解析 + Selenium 自动化 + Tkinter 多线程 GUI

Python 实战项目:网页 JS 数据解析 + Selenium 自动化 + Tkinter 多线程 GUI 文章目录一、整体项目介绍二、基础配置与工具函数三、分页提取歌手歌曲列表四、解密页面加密下载链接五、Selenium Edge 自动化批量转存六、Tkinter GUI 多线程解决界面卡死七、主业务流程 crawl 函数八、项目踩坑总结一、整体项目介绍本工具完整工作流程 输入歌手名字 → 分页提取歌手全部歌曲列表 → 解析歌曲详情页解密 Base64 加密下载链接 → 将结果保存本地 TXT →可选 Selenium自动批量转存。技术栈requests网络请求会话维持BeautifulSoup4HTML 页面 DOM 解析tkinterPython 内置 GUI 图形界面threading queue多线程解决 GUI 阻塞线程安全日志seleniumEdge 浏览器自动化操作实现网盘批量转存pip install requests beautifulsoup4 selenium二、基础配置与工具函数这一部分是全局请求头、请求延时配置、base64 解码工具、线程安全日志队列。关键点网站返回 Base64 经常丢失填充位解码前自动补齐否则直接抛出异常使用队列解决多线程向 GUI 输出日志的线程安全问题。核心代码片段import base64 import queue import requests # 全局请求配置防反爬 REQUEST_SLEEP 1.5 HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36, Referer: https://www.gequbao.com/, } session requests.Session() session.headers.update(HEADERS) LOG_Q queue.Queue() # 跨线程日志队列 def log(msg): 线程安全日志子线程把消息丢入队列GUI主线程读取渲染 LOG_Q.put(msg) def b64_decode(s): base64解码自动补齐缺失的填充位解决网页返回不标准base64字符串问题 s s.strip() s * (-len(s) % 4) return base64.b64decode(s).decode(utf-8, errorsignore)三、分页提取歌手歌曲列表访问主页做分页遍历解析页面 DOM拿到每首歌的歌曲名称、歌曲 ID。 通过歌曲 ID后续才可以进入详情页解析真实下载链接。核心代码片段from bs4 import BeautifulSoup def fetch_song_list(topic_url, page_num): url f{topic_url}?page{page_num} resp session.get(url, timeout15) soup BeautifulSoup(resp.text, html.parser) songs [] # 解析每一行歌曲提取标题和歌曲id rows soup.select(div.row.no-gutters.py-2d5) for row in rows: a_tag row.select_one(div.col-9 a[href^/music/]) if not a_tag: continue title a_tag.get_text(stripTrue).strip() m re.search(r/music/(\d), a_tag.get(href, )) if m and title: songs.append((title, m.group(1))) # 获取最大页码用于循环分页 page_span soup.find(span, stringlambda x: x and / in x) max_page 1 if page_span: mm re.search(r/\s*(\d), page_span.text) if mm: max_page int(mm.group(1)) return songs, max_page四、解密页面加密下载链接整个爬虫最关键部分。网站不会直接返回网盘地址把分享链接放在页面 JS 变量window.appData做了 Base64 加密。 流程请求歌曲详情页 → 正则截取页面内嵌 JSON 字符串 → 处理 unicode 转义 → json 反序列化 → 获取加密字符串 → base64 解码还原真实网盘 URL。import re import json def extract_download_link(mid): detail_url fhttps://www.gequbao.com/music/{mid} resp session.get(detail_url, timeout15) # 正则提取页面JS里面appData的json字符串 m re.search(rwindow\.appData\s*\s*JSON\.parse\((.*?)\)\s*;, resp.text, re.S) if not m: return None, None raw m.group(1) # 处理unicode转义字符加载json raw raw.encode(utf-8).decode(unicode_escape) data json.loads(raw) # 获取base64加密后的分享链接 extra data.get(mp3_extra_urls) or [] if not extra: return None, None share_b64 extra[0].get(share_link, ) # base64解码拿到真实夸克网盘链接 real_url b64_decode(share_b64) return data.get(mp3_author, 未知), real_url五、Selenium Edge 自动化批量转存下载链接抓取完所有链接后调用 selenium 打开 Edge 浏览器用户手动登录夸克网盘程序自动访问每一条分享链接自动点击「保存到网盘」按钮。坑点网站前端经常改版按钮文本、class 会变不能写死单个 xpath使用多套 xpath 循环尝试定位按钮设置足够延时规避网盘风控。核心代码片段from selenium import webdriver from selenium.webdriver.edge.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time def quark_batch_save(links): options Options() options.add_argument(--disable-blink-featuresAutomationControlled) driver webdriver.Edge(optionsoptions) driver.get(https://pan.quark.cn/) # 等待用户手动登录 input( 登录完成后按回车开始批量转存... ) for url in links: driver.get(url) time.sleep(4) # 多套xpath兼容页面不同版本的保存按钮 for xpath in [ //button[contains(.,保存到网盘)], //button[contains(.,转存)], //button[contains(.,保存)], ]: try: btn WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, xpath))) btn.click() break except Exception: continue # 点击弹窗确认保存 for xpath in [//button[contains(.,保存)],//button[contains(.,确定)]]: try: confirm WebDriverWait(driver,4).until(EC.element_to_be_clickable((By.XPATH, xpath))) confirm.click() except Exception: continue time.sleep(2) driver.quit()六、Tkinter GUI 多线程解决界面卡死重点网络 IO 爬虫任务非常耗时如果直接跑在 GUI 主线程tk 窗口直接卡死、无响应。 解决方案爬虫任务放到threading子线程运行子线程日志不直接操作文本框全部 put 到队列GUI 主线程用after()定时器循环读取队列消息刷新 UI设置全局停止标志位实现点击停止按钮随时终止爬虫任务。核心代码片段核心代码片段import tkinter as tk from tkinter import ttk, scrolledtext import threading STOP_FLAG {stop: False} def on_start(entry, auto_var): singer entry.get().strip() # 爬虫任务放到子线程执行防止GUI卡死 t threading.Thread( targetcrawl, # crawl为主业务函数 args(singer, bool(auto_var.get())), daemonTrue, ) t.start() def on_stop(): # 修改停止标记子线程循环检测这个标记实现中断 STOP_FLAG[stop] True log(⏹ 已请求停止...) def poll_queue(log_box): GUI主线程定时读取队列刷新日志文本框线程安全更新UI try: while True: msg LOG_Q.get_nowait() log_box.insert(tk.END, msg \n) log_box.see(tk.END) except queue.Empty: pass log_box.after(150, lambda: poll_queue(log_box)) def build_gui(): root tk.Tk() root.title(歌曲宝抓取 夸克自动转存仅学习) root.geometry(820x600) # ...省略界面组件创建代码... poll_queue(log_box) root.mainloop()七、主业务流程 crawl 函数串联全部模块拼接歌手地址、分页循环提取歌曲、循环解析每首歌下载链接、写入本地 TXT 文件判断是否开启自动转存。核心代码片段def crawl(singer_name, auto_quark): STOP_FLAG[stop] False save_dir singer_name os.makedirs(save_dir, exist_okTrue) out_path os.path.join(save_dir, f{singer_name}_歌曲链接.txt) encoded urllib.parse.quote(singer_name) topic_url fhttps://www.gequbao.com/s/{encoded} # 1.分页抓取全部歌曲 all_songs [] page 1 while True: if STOP_FLAG[stop]: break log(f---- 抓取第 {page} 页 ----) songs, page_max fetch_song_list(topic_url, page) all_songs.extend(songs) if page page_max: break page 1 time.sleep(PAGE_SLEEP) quark_links [] # 2.循环解析每首歌写入txt with open(out_path, w, encodingutf-8) as f: for idx, (title, mid) in enumerate(all_songs,1): if STOP_FLAG[stop]: break author, url extract_download_link(mid) if url and pan.quark.cn in url: quark_links.append(url) log(f✅ {title} - {url}) f.write(f{title} : {url}\n) f.flush() time.sleep(REQUEST_SLEEP) log(f链接保存完成共获取夸克链接 {len(quark_links)} 条) # 3.开启自动转存则调用selenium if auto_quark and quark_links: quark_batch_save(quark_links)八、项目踩坑总结GUI 界面卡死网络 IO 任务必须放到子线程禁止子线程直接操作 tk 组件通过queue队列中转消息。Base64 解码报错网页返回的 base64 字符串经常缺少末尾填充符号解码前动态补齐长度。网页元素动态变更网页改版会修改按钮 class、文字不要写死单条 xpath多组表达式依次尝试。优雅停止任务不能直接 kill 线程设置全局 flag在循环中判断标记实现安全终止爬虫。总结✨拓展改进思路可以留给读者自己玩增加链接有效性检测过滤已经失效的夸克分享链接导出为 Excel 表格增加多线程并发解析详情页注意控制并发数防止封 IP适配下载等其他类型分享链接。完整源码网盘链接如下仅供学习。百度网盘链接通过网盘分享的文件爬取网站音乐源代码链接: https://pan.baidu.com/s/15BFBB3lGtzvJ_cE8ODM-sQ?pwd3f9x 提取码: 3f9x夸克网盘链接我用夸克网盘给你分享了「爬取音乐网站源代码」点击链接或复制整段内容打开「夸克网盘APP」即可获取。/~3a223bDiqd~:/链接https://pan.quark.cn/s/c29dfa689d0c?pwdHHa9提取码HHa9
返回列表