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

for循环更新字典仅保留最后一次爬取数据的问题排查

问题根本原因

两个核心逻辑错误导致最终输出仅保留最后一页数据:

  • 字典key唯一性触发覆盖:所有待爬页面结构完全一致,从表格中提取的字段名(即字典键/key)完全相同。Python原生字典的key具有全局唯一性,当你在循环中反复调用final_dict.update()传入同key的键值对时,新传入的值会直接替换掉该key对应的旧值,循环执行完后自然只会保留最后一个页面的所有字段值。
  • DataFrame构造逻辑不符合需求:你最后使用pd.DataFrame([final_dict])构造表格时,是把整个字典作为单行数据传入,就算不存在key覆盖问题,最终也只会生成1行数据,完全无法承载多页的多行数据。

额外隐患:外层循环遍历页面列表时使用i作为循环变量,内层遍历标签、数据节点时也复用i作为循环变量,属于变量名污染,后续新增逻辑时很容易引发非预期的变量覆盖错误。

修复方案

不要用单个字典存储所有页面的数据,改用列表逐页存储结果:每爬完一个页面,就把当前页两个表格合并后的字典作为独立元素追加到结果列表中,最后直接把整个列表传入pd.DataFrame()即可,列表中的每个字典会自动对应DataFrame的一行,从根源上避免同key覆盖的问题。

修正后的可运行代码:

import requests
from bs4 import BeautifulSoup
import pandas as pd

pages = ['https://example.com/page1.html',
         'https://example.com/page2.html']

# 初始化列表存储每一页的结果,替代原来的单个字典
result_list = []

for url in pages: 
    r = requests.get(url)
    soup = BeautifulSoup(r.content, 'html.parser')
    
    # 解析第一个表格
    first_table = soup.select_one("table:nth-of-type(1)")
    # 提取标签文本
    label_filter = []
    labels = first_table.find_all('td', class_='label')
    for label in labels:
        label_filter.extend(label.find_all('span', class_='txt'))
    label_filter_txt = [item.text for item in label_filter]
    # 提取对应数据文本
    label_data = []
    datapoints = first_table.find_all('td', class_='data')
    for point in datapoints:
        label_data.extend(point.find_all('span', class_='txt'))
    label_data_txt = [item.text for item in label_data]
    first_table_dict = dict(zip(label_filter_txt, label_data_txt))

    # 解析第二个表格
    second_table = soup.select_one("table:nth-of-type(2)")
    # 提取标签文本
    label_filter = []
    labels = second_table.find_all('td', class_='label')
    for label in labels:
        label_filter.extend(label.find_all('span', class_='txt'))
    label_filter_txt = [item.text for item in label_filter]
    # 提取对应数据文本
    label_data = []
    datapoints = second_table.find_all('td', class_='data')
    for point in datapoints:
        label_data.extend(point.find_all('span', class_='txt'))
    label_data_txt = [item.text for item in label_data]
    second_table_dict = dict(zip(label_filter_txt, label_data_txt))

    # 合并当前页两个表格的数据,追加到结果列表
    page_dict = {}
    page_dict.update(first_table_dict)
    page_dict.update(second_table_dict)
    result_list.append(page_dict)

# 直接传入结果列表构造DataFrame,每个元素对应一行数据
df = pd.DataFrame(result_list)

如果你有特殊需求必须把所有数据存在同一个字典而非按行存储,只需要给每个页面的字段key加上唯一标识即可,比如将key调整为{page_index}_{field_name}格式,保证不同页面的key不重复就不会触发覆盖。但从生成结构化二维表格的需求来看,用列表逐行存储是最简洁、性能最优的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:54:20