Python循环创建嵌套字典时避免值被覆盖的技术咨询
解决爬虫循环中嵌套字典被覆盖的问题
这个问题我之前写爬虫时也踩过一模一样的坑!核心原因是你的scrape_doc_info函数大概率没有每次调用都创建新的字典对象,而是一直在复用同一个字典的引用——Python里可变对象(比如字典)的赋值是传递引用,不是复制内容,所以all_data_dict里的所有键都会指向同一个字典实例,每次循环修改这个字典的内容时,所有旧的引用也会跟着更新,最后就全变成最后一次爬取的数据了。
具体解决方案分两种情况:
1. 修改scrape_doc_info函数(推荐)
最根本的解决办法是确保scrape_doc_info每次调用都在内部新建一个字典,而不是复用外部定义的字典。比如把原来可能在函数外定义的字典移到函数内部:
def scrape_doc_info(link, tag_list, selector_dict): # 关键:每次调用都创建全新的字典对象 doc_info = {} doc_info["Url"] = link # 这里写你的HTML标签提取逻辑,比如: # doc_info["Document Title"] = 提取到的页面标题 # doc_info["Release Date"] = 提取到的发布日期 return doc_info
这样每次调用函数都会返回一个独立的字典,赋值给all_data_dict的不同键时,它们之间就不会互相影响了。
2. 无法修改scrape_doc_info时,使用深拷贝
如果因为某些原因不能修改scrape_doc_info,那就在create_dict里对函数返回的字典做深拷贝,强制生成一个新的独立字典对象:
import copy def create_dict(link_list): all_data_dict = {} count = 0 for link in link_list: # 用深拷贝复制返回的字典,避免引用同一个对象 doc_data = copy.deepcopy(scrape_doc_info(link, tag_list, selector_dict)) all_data_dict[count] = doc_data count += 1 return all_data_dict
为什么会出现覆盖现象?
用一个简单的模拟例子就能看明白:
# 模拟你的scrape_doc_info复用同一个字典的情况 shared_dict = {} def fake_scrape(link): shared_dict["Url"] = link return shared_dict all_data = {} for i, link in enumerate(["test1", "test2"]): all_data[i] = fake_scrape(link) print(all_data) # 输出会是 {0: {'Url': 'test2'}, 1: {'Url': 'test2'}}
因为fake_scrape每次返回的都是shared_dict的引用,all_data[0]和all_data[1]指向的是同一个字典,最后一次修改会覆盖所有引用的内容。
内容的提问来源于stack exchange,提问作者Solar
相关产品推荐
相关产品推荐

