Python报'dict' object has no attribute 'append'错误解决方法
问题现象
编写Python爬虫抓取全国五金展参展商列表数据时,设计循环逻辑持续追加存储接口返回的参展商名称、邮箱、电话、官网、地址、代理品牌信息,运行代码时抛出AttributeError: 'dict' object has no attribute 'append'错误,原实现代码如下:
import requests from bs4 import BeautifulSoup import json import pandas as pd headers = { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8,pt;q=0.7', 'Connection': 'keep-alive', 'Origin': 'https://www.nationalhardwareshow.com', 'Referer': 'https://www.nationalhardwareshow.com/', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'cross-site', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', 'accept': 'application/json', 'content-type': 'application/x-www-form-urlencoded', 'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', } base_url='https://api.reedexpo.com/v1/organisations/' params = { 'x-algolia-agent': 'Algolia for vanilla JavaScript 3.27.1', 'x-algolia-application-id': 'XD0U5M6Y4R', 'x-algolia-api-key': 'd5cd7d4ec26134ff4a34d736a7f9ad47', } data = '{"params":"query=&page=0&facetFilters=&optionalFilters=[]"}' resp = requests.post('https://xd0u5m6y4r-3.algolianet.com/1/indexes/event-edition-eve-e6b1ae25-5b9f-457b-83b3-335667332366_en-us/query', params=params, headers=headers, data=data).json() productlinks=[] for item in resp['hits']: url=base_url+item['organisationGuid']+"/exhibiting-organisations?eventEditionId="+item['eventEditionExternalId'] productlinks.append(url) data=[] for link in productlinks: headers = {"x-clientid": "uhQVcmxLwXAjVtVpTvoerERiZSsNz0om"} data = requests.get(link, headers=headers).json() wev={} for t in data["_embedded"]: name=t['companyName'] wev['name']=name email=t['email'] wev['Email']=email telephone=t["phone"] wev['Telephone']=telephone link=t['website'] wev['link']=link d=t["multilingual"] for u in d: k=u["address"] wev['address']=k n=u["representedBrands"] wev['brand']=n data.append(wev) df=pd.DataFrame(data) print(df)
错误根因
- 核心触发原因是变量名冲突覆盖:代码先初始化了用于存储全量参展商数据的列表
data=[],但在循环请求详情接口时,直接用data = requests.get(...).json()接收接口返回的字典类型响应,原本的列表变量被字典覆盖。后续执行data.append(wev)时,调用对象已经是字典,字典不存在append方法,直接抛出属性错误。 - 附带隐藏逻辑bug:单条参展商数据字典
wev定义在遍历循环外层,循环过程中反复修改同一个字典对象的键值,最终列表中存储的所有条目都会指向最后一次赋值的内容,出现全量数据重复的问题;同时代码未做字段存在性校验,遇到接口返回缺字段的条目时会触发KeyError中断运行。
修复步骤
- 重命名存储全量结果的列表变量,和接口响应变量做明确区分,比如将存储列表改名为
exhibitor_list,彻底避免变量覆盖。 - 调整
wev字典的初始化位置,每次处理单条参展商/单条多语言记录时新建独立字典,避免引用同一个字典对象导致的数据覆盖。 - 增加字段容错逻辑,通过
.get()方法读取字段,缺字段时赋值为空值,避免程序意外中断。
修复后可正常运行的代码如下:
import requests import pandas as pd headers = { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8,pt;q=0.7', 'Connection': 'keep-alive', 'Origin': 'https://www.nationalhardwareshow.com', 'Referer': 'https://www.nationalhardwareshow.com/', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'cross-site', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', 'accept': 'application/json', 'content-type': 'application/x-www-form-urlencoded', 'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', } base_url='https://api.reedexpo.com/v1/organisations/' params = { 'x-algolia-agent': 'Algolia for vanilla JavaScript 3.27.1', 'x-algolia-application-id': 'XD0U5M6Y4R', 'x-algolia-api-key': 'd5cd7d4ec26134ff4a34d736a7f9ad47', } search_data = '{"params":"query=&page=0&facetFilters=&optionalFilters=[]"}' resp = requests.post('https://xd0u5m6y4r-3.algolianet.com/1/indexes/event-edition-eve-e6b1ae25-5b9f-457b-83b3-335667332366_en-us/query', params=params, headers=headers, data=search_data).json() productlinks=[] for item in resp['hits']: detail_url = base_url + item['organisationGuid'] + "/exhibiting-organisations?eventEditionId=" + item['eventEditionExternalId'] productlinks.append(detail_url) # 重命名存储全量数据的列表,避免和接口响应变量冲突 exhibitor_list = [] for link in productlinks: detail_headers = {"x-clientid": "uhQVcmxLwXAjVtVpTvoerERiZSsNz0om"} # 接口响应用独立变量名接收 detail_resp = requests.get(link, headers=detail_headers).json() for t in detail_resp["_embedded"]: # 每处理一个参展商新建独立字典 wev = { 'name': t.get('companyName', ''), 'Email': t.get('email', ''), 'Telephone': t.get('phone', ''), 'link': t.get('website', '') } multi_lang_list = t.get("multilingual", []) for u in multi_lang_list: # 多语言条目复制独立字典存储,避免覆盖 item_data = wev.copy() item_data['address'] = u.get('address', '') item_data['brand'] = u.get('representedBrands', '') exhibitor_list.append(item_data) df = pd.DataFrame(exhibitor_list) print(df)
内容的提问来源于stack exchange,提问作者Amen Aziz
相关产品推荐
相关产品推荐

