资讯动态

25 行 Python,下一首歌

发布时间:2026/10/28 1:42:43 来源:尧图企业网站定制
25 行 Python下一首歌我常被人问Python 爬虫到底能写多短。以前我会甩一段 50 行、80 行的代码出来今天我想给你看一段真正极简的——25 行不到把一首歌从搜索到落盘完整跑通。看完你会发现所谓爬虫工程师做的事情没那么神秘大部分时候就是搜页 → 详情页 → 播放 API → 写文件这四步。先看完整脚本importrequestsfromlxmlimportetreeimportjson urlhttps://www.gequbao.com/s/%E5%91%A8%E6%9D%B0%E4%BC%A6headers{user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36,}resrequests.get(urlurl,headersheaders)dataetree.HTML(res.text)infodata.xpath(//div[classcol-9 col-md-8])# 每首歌一个 divforiininfo[0:3]:titlei.xpath(.//span/text())[0].strip()# 第一跳列表页 → 详情页aurli.xpath(./a/href)[0]zwurlhttps://www.gequbao.comaurl zwdatarequests.get(zwurl,headersheaders).text.replace(\\u0022,)# 从详情页源码里挖出 play_idpidzwdata.split(play_id:)[1].split()[0]# 第二跳详情页 → 真实下载地址apihttps://www.gequbao.com/api/play-urlgequrequests.post(api,headersheaders,data{id:pid}).json()musicurlgequ[data][url]# 落盘muresrequests.get(musicurl,headersheaders)withopen(f{title}.mp3,wb)asf:f.write(mures.content)25 行。真的就这么多。为什么是 xpath不是正则很多新人爬虫教程一上来就教re.findall但真正工业级的爬虫几乎不用正则匹配 HTML。原因有三HTML 是结构化文档xpath 走的是 DOM 树能直接锁定第 N 层 / 第 N 个 / 某个 class 的子节点比正则写出来的魔法串好读太多DOM 是容错的——标签多一个空格、少一个换行xpath 一般照常命中正则经常挂现代浏览器 DevTools 自带Copy XPath开发者不用手写表达式。对应到代码里这一行infodata.xpath(//div[classcol-9 col-md-8])意思就是在整棵 DOM 树里找所有 class 同时包含col-9和col-md-8的 div——这两列类名是 Bootstrap 栅格的写法几乎不会和其它 div 撞车是相当稳的锚点。列表页拿到的是半截链接注意这一行aurli.xpath(./a/href)[0]zwurlhttps://www.gequbao.comaurl列表页的a href/music/8475848给你的是相对路径必须手动拼上 origin。这种半截链接在爬虫里非常常见看到href没带协议头就要长个心眼。详情页里挖play_id是个字符串手术pidzwdata.split(play_id:)[1].split()[0]这一行长得丑但理解了就通——把整段 HTML 源码当成字符串先按play_id:切成两半第二段里再按切第一个就是纯净的 id。为什么不直接用正则因为play_id在页面上是个内嵌 JSON的字段被网站为了反爬故意把双引号转义成\u0022。replace(\\u0022, )是先做一步反转义把字符串还原成正常 JSON再做字符串切割。看起来像正则的活本质是字符串手术。POST 请求把 id 喂回去换链接gequrequests.post(api,headersheaders,data{id:pid}).json()musicurlgequ[data][url]这一步是整个脚本的灵魂。注意三件事走的是POST不是GET——参数在请求体里不在 URL 里浏览器历史和日志看不到相对更隐蔽提交的是data{id: pid}这是表单格式如果对方要 JSON要换成json{id: pid}返回的是 JSON所以直接.json()拿到字典再走[data][url]拿真正的 mp3 直链。这一套前端拼请求、后端发请求的链条几乎所有内容站都在用——B 站、抖音、知乎、闲鱼只是字段名不同而已。写到本地的最后一步withopen(f{title}.mp3,wb)asf:f.write(mures.content)两件事千万别搞错模式必须是wb二进制写。mp3 是字节流用w会在 Windows 上因为编码问题坏文件写的是mures.content不是mures.text。.text是字符串自动解码.content是 bytes原始字节流下任何媒体文件都用.content。25 行背后看不见的事脚本跑起来当然没那么丝滑真正写爬虫的功夫都在脚本之外请求头要伪装裸requests.get经常被 403UA、Referer、Cookie 至少要有一个。频率要克制循环里没加time.sleep一分钟内连发几十个请求IP 几分钟就被封。生产代码建议加random.uniform(1, 3)。要断点续跑网络断一次就要从头来。可以先把列表页的歌曲 id 列表落盘到 JSON循环读 JSON没下完的标记pending下次接着跑。要去重同一首歌经常在多个搜索结果里出现最终写入前用if title not in done_titles跳过。要日志每首歌的状态打到一个log.txt失败重试。这些脚本之外的工程化能力恰恰是从作业到生产的分水岭。把这套打法套到任何内容站这套列表页拿 id → 详情页拿播放参数 → POST/API 换直链 → 落盘的四步法几乎可以套用到所有 UGC 站点B 站__playinfo__里找baseUrl抖音分享链接里解析aweme_id再去/api/aweme/v1/aweme/detail/拿视频流知乎问题的/api/v4/questions/{id}/answers拿回答列表公众号文章__NEXT_DATA__里有正文 HTML。字段名千变万化思路只有一套。写在最后爬虫从来不是写得多就是高手写得多不代表写得好。一段 25 行的脚本里藏着对 HTTP、对 HTML、对 JSON、对文件 IO 的完整闭环把它读懂、改熟、举一反三比刷十份 500 行的大项目有用得多。下一步建议做三件事把 UA 和 Cookie 挪进os.environ用asyncio aiohttp改成并发下载给每首歌写一个 SHA1 比对跳过已下载文件。做完这三件事你手里就不再是作业脚本而是一个真正能用的工具。最后留一句抓得到不等于抓得对。所有抓回来的数据第一时间想清楚怎么用、用在哪、给谁看——技术是手段问题才是起点。免责声明请务必读完写到这里必须把丑话讲在前面。本文的代码与思路仅用于技术学习和个人研究请务必遵守以下边界尊重版权与平台规则。绝大多数音乐平台的用户协议都明确禁止未经授权的批量下载、绕过付费墙、二次分发。脚本能跑不代表你有权跑——能下到不等于你拥有。下载到的 mp3 只供你个人试听、学习请勿上传网盘、转载、公开传播更不要用于任何商业用途。不破坏平台正常运行。循环里没有 sleep、并发过高、伪造身份绕过付费/登录墙——这些都是《网络安全法》《数据安全法》和《刑法》第 285、286 条里可能踩到的雷。商业爬虫合规问题请咨询律师不要拿个人学习当万能挡箭牌。保护好你自己的账号。脚本里所有 Cookie / SESSDATA / 登录 token 都属于个人敏感凭据。任何公开仓库、博客、社交媒体、聊天群截图里都不要贴真实凭据。本文代码块里的YOUR_xxx_HERE不是装饰是底线。网站结构随时变。今天能用的接口、XPath、字段名明天可能就403或改名。代码示例仅供学习思路实际使用请以目标站点当前接口为准自负其责。出了问题与本文无关。脚本运行造成的账号封禁、设备损坏、数据丢失、法律纠纷均由使用者自行承担。技术是工具不是免责符。如果你看完觉得原来爬虫这么简单请把这份简单用在合法、正当、有边界的场景里——这是我能给你的最后一点职业建议。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑