
本文详解 python 脚本如何利用 discogs 官方 api 实现两级请求:先搜索专辑列表,再逐个请求单张唱片详情页以提取嵌入的 youtube 视频 url。关键在于区分搜索结果接口(无 videos 字段)与单资源详情接口(含 videos 数组)。
本文详解 python 脚本如何利用 discogs 官方 api 实现两级请求:先搜索专辑列表,再逐个请求单张唱片详情页以提取嵌入的 youtube 视频 url。关键在于区分搜索结果接口(无 videos 字段)与单资源详情接口(含 videos 数组)。
Discogs 提供了结构清晰的 RESTful API,但其数据分布具有层级性:搜索端点(/database/search)仅返回元数据摘要(如标题、年份、格式),不包含视频信息;而单张唱片详情端点(/releases/{id})才在响应中提供 videos 字段。原始脚本正是基于这一设计,采用“广度优先 + 队列驱动”的方式完成两级爬取。
核心逻辑解析
-
第一级:获取发行列表(Search Endpoint)
初始请求指向https://api.discogs.com/database/search?...,返回 JSON 包含:-
results: 每项为一个 release 的简要信息,含resource_url(如"https://api.discogs.com/releases/1136089"); -
pagination.urls.next: 下一页搜索结果地址(用于翻页)。
此阶段
data中确实没有videos键——这是正常且预期的行为。 -
-
第二级:获取单张唱片详情(Release Endpoint)
脚本将每个result['resource_url']加入队列,并发起新请求(如GET https://api.discogs.com/releases/1136089?token=...)。该端点返回的 JSON 结构完全不同,典型响应如下:{ "id": 1136089, "title": "Exos - Yellow Yard", "videos": [ { "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "duration": 245, "description": "Official video" } ] }✅ 此时
'videos' in data才为True,脚本能安全遍历并提取video['uri']。
为什么你的调试脚本没看到 videos?
你只执行了第一级请求(INITIAL_URL),即搜索接口,因此 data 是分页列表结构,自然不含 videos。要验证第二级行为,可手动请求一个 resource_url:
# 示例:直接请求某张唱片详情(替换为实际 ID)
detail_url = "https://api.discogs.com/releases/1136089?token=YOUR_TOKEN"
detail_data = discogs_request(detail_url)
print("'videos' in detail_data:", 'videos' in detail_data) # 输出 True
if 'videos' in detail_data:
for v in detail_data['videos']:
print("YouTube URL:", v['uri'])
推荐优化写法(去队列版)
若希望逻辑更直观,可改用嵌套循环替代队列(适合中小规模数据):
import requests
from urllib.parse import urlparse, parse_qs
def discogs_request(url):
headers = {'User-agent': 'DiscogsVideoExtractor/1.0'}
response = requests.get(url, headers=headers)
if response.status_code == 429:
time.sleep(60)
return discogs_request(url)
return response.json() if response.status_code == 200 else None
SEARCH_URL = "https://api.discogs.com/database/search?sort=title&sortorder=desc&style=Dub+Techno&format=Vinyl&type=release&year=1999&per_page=50"
ACCESS_TOKEN = "your_token_here"
PAGE_LIMIT = 25
with open('video_urls.txt', 'w') as f:
current_url = f"{SEARCH_URL}&token={ACCESS_TOKEN}"
for page_num in range(1, PAGE_LIMIT + 1):
data = discogs_request(current_url)
if not data or 'results' not in data:
break
# 处理当前页所有唱片
for release in data['results']:
detail_url = f"{release['resource_url']}?token={ACCESS_TOKEN}"
detail = discogs_request(detail_url)
if detail and 'videos' in detail:
for video in detail['videos']:
f.write(video['uri'] + '\n')
print(f"✓ Saved: {video['uri']}")
# 获取下一页 URL
next_url = data.get('pagination', {}).get('urls', {}).get('next')
if not next_url:
break
current_url = next_url
注意事项与最佳实践
-
API 限流:Discogs 对未认证请求严格限频,务必使用有效
access_token(在 Developers Settings 申请); -
错误处理:生产环境需增加超时、重试、空响应兜底(如
if not detail: continue); -
字段可靠性:
videos是可选字段,部分唱片可能无关联视频,务必用if 'videos' in data:判断; -
User-Agent 合规性:必须设置真实、可识别的
User-agent头,避免被封禁; - 数据许可:提取的 YouTube 链接仅作个人用途,不得用于商业分发或绕过平台规则。
通过理解 Discogs API 的资源层级关系,你就能精准定位视频数据所在位置,避免在错误响应中徒劳查找 videos 键。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











