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

请求协助调试Kodi插件Python脚本以适配新网站爬取需求

解决不规范HTML结构的Kodi插件爬取问题

碰到标签混乱、完全不按规范来的网站确实头疼——毕竟大部分爬虫教程都是基于清晰的class、id或者层级结构来写的。不过别慌,针对这种野路子网站,我们可以换几种思路来定位元素,再结合你的现有代码调整,就能搞定那4个字段的爬取了。

一、定位不规范HTML元素的核心技巧

先给你几个实用的方法,不管网站结构多乱,总能找到突破口:

  • 靠文本内容+标签层级定位:如果元素有固定的文本(比如“播放音频”“第X集”),可以先找到包含这段文本的标签,再通过find_parent()、find_next_sibling()去拿它附近的目标内容。比如你要找音频链接,先找到写着“收听”的按钮,再找它的父容器里的<a>标签。
  • CSS选择器的“硬定位”:BeautifulSoup支持CSS选择器,比如用select("div > p:nth-of-type(3)")直接选某个div下的第三个p标签,不管它有没有class。这种方法适合结构固定但没有标识的情况。
  • 正则匹配属性值:如果目标元素的属性(比如href、src)有规律(比如都包含“episode”或者“.mp3”),可以用正则来筛选,比如find_all("a", href=re.compile(r"\.mp3$"))就能抓所有音频链接。
  • 暴力遍历DOM树:实在没辙的时候,就从根节点开始逐层遍历,比如先抓所有<div>标签,然后循环每个div,检查里面有没有你要的内容——虽然笨,但对付混乱结构特别有效。

二、结合你的代码修改示例

假设你要爬的4个字段是标题、音频链接、封面图、发布日期,我给你改一下核心的parse_page和build_song_list函数,你可以根据目标网站的实际结构调整细节:

首先,别忘了导入正则模块:

import re

然后重写parse_page函数,这里的选择器都是示例,你需要对照目标网站的HTML结构修改:

def parse_page(page):
    episodes = {}
    index = 1
    # 先找到所有可能的剧集容器(比如目标网站里每个剧集都在一个无class的div里)
    for episode_block in page.find_all("div"):
        # 1. 定位标题:假设标题在h3标签里,文本带“第X集”字样
        title_tag = episode_block.find("h3", text=re.compile(r"第\d+集"))
        if not title_tag:
            continue  # 不是我们要的剧集块,跳过
        title = title_tag.get_text(strip=True)
        
        # 2. 定位音频链接:找href以.mp3结尾的a标签
        audio_link_tag = episode_block.find("a", href=re.compile(r"\.mp3$"))
        if not audio_link_tag:
            continue
        audio_url = audio_link_tag["href"]
        # 处理相对链接,补全域名
        if not audio_url.startswith(("http://", "https://")):
            audio_url = f"https://目标网站域名{audio_url}"
        
        # 3. 定位封面图:找src里包含“cover”的img标签
        cover_tag = episode_block.find("img", src=re.compile(r"cover"))
        cover_url = cover_tag["src"] if cover_tag else ""
        if cover_url and not cover_url.startswith(("http://", "https://")):
            cover_url = f"https://目标网站域名{cover_url}"
        
        # 4. 定位发布日期:找文本格式为YYYY-MM-DD的span标签
        date_tag = episode_block.find("span", text=re.compile(r"\d{4}-\d{2}-\d{2}"))
        publish_date = date_tag.get_text(strip=True) if date_tag else ""
        
        # 把字段存入字典
        episodes[index] = {
            "title": title,
            "audio_url": audio_url,
            "cover_url": cover_url,
            "publish_date": publish_date
        }
        index += 1
    return episodes

接着调整build_song_list函数,适配新的字段:

def build_song_list(episodes):
    episode_list = []
    for idx in episodes:
        ep = episodes[idx]
        # 用标题作为列表项显示文本,封面作为缩略图
        li = xbmcgui.ListItem(label=ep['title'], thumbnailImage=ep['cover_url'])
        li.setProperty('fanart_image', ep['cover_url'])
        li.setProperty('IsPlayable', 'true')
        # 可选:把发布日期添加到列表项的信息里,Kodi会显示出来
        li.setInfo('music', {'title': ep['title'], 'date': ep['publish_date']})
        # 构建播放用的插件链接
        url = build_url({'mode': 'stream', 'url': ep['audio_url'], 'title': ep['title']})
        episode_list.append((url, li, False))
    # 把列表添加到Kodi的目录里
    xbmcplugin.addDirectoryItems(addon_handle, episode_list, len(episode_list))
    xbmcplugin.setContent(addon_handle, 'episodes')  # 改成剧集类型更贴合内容
    xbmcplugin.endOfDirectory(addon_handle)

三、调试小技巧

  • 保存页面到本地:在get_page函数里,把请求到的HTML保存成文件,比如:
    def get_page(url):
        response = requests.get(url)
        with open("target_page.html", "w", encoding="utf-8") as f:
            f.write(response.text)
        return BeautifulSoup(response.text, 'html.parser')
    
    然后用浏览器打开这个本地文件,右键“检查元素”,慢慢找你要的字段所在的位置,比直接看线上源码方便多了。
  • 分步测试:先单独运行parse_page函数,打印每个字段的结果,确认能正确抓取后,再整合到Kodi插件里调试,避免一起出问题不好排查。
  • 灵活调整选择器:如果某个标签的位置偶尔变动,别死磕一个选择器,比如可以先抓所有<a>标签,然后循环检查每个a的href是不是音频链接,总能找到规律。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:37:14