You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决iTunes API无法返回部分播客feed URL的问题?

问题描述

通过iTunes API的search和lookup端点爬取播客feed URL时,发现部分播客的API响应中缺失feedUrl字段,导致无法获取目标信息。目前已尝试通过播客ID调用lookup端点,多数情况正常,但仍有部分播客无该字段,需要替代方案推进爬取工作。

现有代码
import re
import requests
import json
import sqlite3
import time

def getrss(url):
    feed_url = ''
    genres = ''

    match = re.search(r'id(\d+)', url)
    if match:
        podID = match.group(1)
    else:
        match = re.search(r'\d+', url)
        if match:
            podID = match.group()
        else:
            print("Aucun identifiant de podcast trouvé")
            return

    params = {
        'id': int(podID),
        'entity': 'podcast'
    }

    response = requests.get('https://itunes.apple.com/lookup', params=params)
    data = response.json()

    results = data.get('results', [])
    if results:
        for result in results:
            if 'feedUrl' in result and 'genres' in result:
                feed_url = result['feedUrl']
                genres = result.get('genres', [])
                genres = ', '.join(genres)
                break

    rss_feed = feed_url
    return rss_feed, genres

# Connexion à la base de données SQLite
conn = sqlite3.connect("podcasts.db")
cursor = conn.cursor()

# Création d'une table pour stocker les données des podcasts
cursor.execute("CREATE TABLE IF NOT EXISTS podcasts (name TEXT, genres TEXT, rss_feed TEXT, UNIQUE(name, genres))")

url = "https://itunes.apple.com/fr/rss/toppodcasts/limit=200/json"

response = requests.get(url)
data = response.json()

if "feed" in data and "entry" in data["feed"]:
    podcasts = data["feed"]["entry"]

    for podcast in podcasts:
        name = podcast.get("im:name", {}).get("label")
        href = podcast.get("id", {}).get("label")
        genres = ""

        if name and href:
            rss_feed, genres = getrss(href)
            if rss_feed:
                try:
                    # Insertion des données du podcast dans la base de données, en ignorant les doublons
                    cursor.execute("INSERT OR IGNORE INTO podcasts (name, genres, rss_feed) VALUES (?, ?, ?)", (name, genres, rss_feed))
                    if cursor.rowcount > 0:
                        time.sleep(0.1)
                        conn.commit()
                except sqlite3.IntegrityError:
                    print("Ignorer l'entrée en double :", name, "-", genres)
            else:
                print("Ignorer l'entrée en raison d'un flux rss caché :", name, "-", genres)
        else:
            print("Ignorer l'entrée en raison de champs manquants :", podcast)

    print("Podcasts enregistrés dans la base de données.")
else:
    print("Aucun podcast trouvé.")

# Fermeture de la connexion à la base de données
conn.close()
解决方案思路

1. 网页抓取补充Feed URL

直接访问播客的Apple Podcasts详情页(通过播客ID构造URL:https://podcasts.apple.com/fr/podcast/id{podID}),用HTML解析工具提取页面中的Feed链接。这是最直接的补充方案,因为播客详情页通常会包含官方Feed地址。

代码修改示例

在原有代码中添加网页抓取的 fallback 逻辑:

from bs4 import BeautifulSoup

def get_feed_from_web(podID):
    feed_url = ""
    url = f"https://podcasts.apple.com/fr/podcast/id{podID}"
    # 模拟浏览器请求头,避免被拦截
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')
        # 查找页面中指定类型的Feed链接
        feed_link = soup.find('link', {'type': 'application/rss+xml'})
        if feed_link:
            feed_url = feed_link.get('href')
    return feed_url

# 修改原getrss函数,加入fallback
def getrss(url):
    feed_url = ''
    genres = ''

    match = re.search(r'id(\d+)', url)
    if match:
        podID = match.group(1)
    else:
        match = re.search(r'\d+', url)
        if match:
            podID = match.group()
        else:
            print("Aucun identifiant de podcast trouvé")
            return

    params = {
        'id': int(podID),
        'entity': 'podcast'
    }

    response = requests.get('https://itunes.apple.com/lookup', params=params)
    data = response.json()

    results = data.get('results', [])
    if results:
        for result in results:
            if 'genres' in result:
                genres = ', '.join(result.get('genres', []))
            if 'feedUrl' in result:
                feed_url = result['feedUrl']
                break

    # API未返回Feed时,尝试抓取网页
    if not feed_url:
        feed_url = get_feed_from_web(podID)
        if feed_url:
            print(f"Feed récupéré depuis la page web pour {podID}")

    return feed_url, genres

2. 第三方播客目录API

使用覆盖范围更广的第三方播客API(如Podcast Index),这类API会收录更多播客的Feed信息,且返回格式更稳定。部分API需要申请密钥,但免费额度通常足够小规模爬取。

3. 批量Feed查询服务

利用专门解析播客Feed的服务,通过Apple播客ID批量查询缺失的Feed URL,作为API失效时的补充方案。

注意事项
  • 所有抓取操作需遵守目标网站的robots.txt规则和服务条款,避免触发反爬机制。
  • 添加适当的请求延迟(如time.sleep(1)),避免频繁请求导致IP被封禁。
  • 对抓取到的Feed URL进行有效性验证,确保能正常访问。

内容的提问来源于stack exchange,提问作者Elliot Moreau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:48:29