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

Python BeautifulSoup如何爬取数量不确定的同级网页元素

爬取实现方案

完全可以通过for循环完成全量发行信息爬取,你现有代码的问题是元素匹配逻辑覆盖不全、没有做跨平台内容截断、值提取逻辑太死板,按以下逻辑调整即可适配元素数量、类型不固定的场景:

  • 遍历页面所有<h2>标签,每个h2对应一个平台的独立发行信息块,避免不同平台内容混杂
  • 逐个遍历h2后的同级元素,遇到下一个h2标签时立刻终止当前平台的采集,自动适配不同平台下发行字段数量不固定的情况
  • 针对floatholder类的字段行,不强制匹配<a>标签取值,直接取字段值容器的纯文本,同时兼容带超链接、纯文本两种值格式
  • 针对非floatholder的普通div,统一识别为发行备注信息存储
  • 遍历过程中直接跳过<hr>、空文本节点这类纯排版用的无内容元素

补全后的可运行代码如下:

import requests
from bs4 import BeautifulSoup
from collections import defaultdict
import pandas as pd

def get_releases(url):
    # 兼容带/不带/release-info后缀的传入url
    if not url.endswith('/release-info'):
        url = url + '/release-info'
    response = requests.get(
        url, 
        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"}
    )
    assert response.status_code == 200, "Problem with url request! %s throws %s" % (
        url,
        response.status_code,
    ) 
    release_soup = BeautifulSoup(response.text, "lxml")
    return release_soup


def get_releases_info(release_soup):
    all_releases = []
    # 提取游戏通用标题
    game_title = release_soup.find('h1').find('a').text.strip()
    # 拿到所有平台对应的h2标题节点
    platform_h2_list = release_soup.find_all('h2')
    
    for h2 in platform_h2_list:
        single_release = defaultdict(str)
        single_release['title'] = game_title
        single_release['platform'] = h2.text.strip()
        release_notes = []
        
        # 遍历当前h2后的所有同级节点
        for sibling in h2.next_siblings:
            # 遇到下一个h2,说明当前平台内容遍历完成,终止循环
            if sibling.name == 'h2':
                break
            # 跳过空节点、排版用的hr分隔线
            if sibling.name in [None, 'hr']:
                continue
            # 处理带floatholder类的标准字段行
            if sibling.name == 'div' and 'floatholder' in sibling.get('class', []):
                field_name = sibling.find('div').text.strip().lower().replace(' ', '_').replace(':', '')
                # 取字段值容器的纯文本,兼容超链接、纯文本两种值形式
                field_value = sibling.find_all('div')[-1].text.strip()
                single_release[field_name] = field_value
            # 处理普通div,即发行补充备注
            elif sibling.name == 'div':
                note_text = sibling.text.strip()
                if note_text:
                    release_notes.append(note_text)
        # 合并所有备注存入结果
        if release_notes:
            single_release['release_note'] = '\n'.join(release_notes)
        all_releases.append(dict(single_release))
    
    # 转换为DataFrame格式
    release_df = pd.DataFrame(all_releases)
    return release_df

# 调用示例
if __name__ == '__main__':
    target_url = "https://www.mobygames.com/game/ps2/007-nightfire/release-info"
    page_soup = get_releases(target_url)
    release_df = get_releases_info(page_soup)
    # 测试打印结果
    print(release_df)
    # 可按需导出为csv文件
    # release_df.to_csv('game_release.csv', index=False, encoding='utf-8-sig')

代码运行后会自动提取页面下所有平台的全量发行信息,最终输出的DataFrame每一行对应一个平台的发行条目,列名自动匹配提取到的字段(如发行商、开发商、发行日期、年龄评级等),无对应字段的位置默认留空,完全适配字段数量不固定的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:09:18