Python使用BS4爬取网页数据时报'int'对象不可下标错误如何解决
错误原因排查与修复方案
具体错误点拆解
- 遍历行的方法错误
原代码用
for row in soup.find('tbody').find('tr'):find('tr')仅返回tbody下的第一个tr标签,遍历单个标签得到的是标签的子节点(包含文本节点、换行符等非标签类型数据),当你拿到int类型的节点时调用相关方法就会出现类型错误,应该改为for row in soup.find("tbody").find_all('tr')遍历所有行。
- 获取列的方法错误
原代码用
col = row.find("td"):find("td")仅返回当前行的第一个td标签,是单个对象不是列表,后续用col[0]下标访问自然会抛出'object is not subscriptable'错误,应该改为col = row.find_all("td")获取当前行所有td标签的列表。
- 变量名不匹配
你提取数据后定义的变量是
Name、Exchange、Sector,但append到DataFrame的时候用了未定义的Company_Name、Exchange_code、Industry,变量名对应不上会触发NameError。
- 弃用方法问题
pandas 2.0+版本已经移除了DataFrame.append方法,继续使用会触发警告或报错,建议先将所有数据存入普通列表,最后一次性转成DataFrame,性能也更高。
修复后可运行代码
import pandas as pd import requests from bs4 import BeautifulSoup url = "https://www.marketwatch.com/tools/markets/stocks/country/sri-lanka/1" # 加请求头避免被反爬拦截 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" } data = requests.get(url, headers=headers).text soup = BeautifulSoup(data, 'html5lib') # 先用列表存数据,性能更高 cse_list = [] for row in soup.find("tbody").find_all('tr'): col = row.find_all("td") if len(col) < 3: # 过滤空行/不完整行 continue Name = col[0].text.strip() Exchange = col[1].text.strip() Sector = col[2].text.strip() cse_list.append({"Name":Name, "Exchange":Exchange, "Sector":Sector}) # 列表转DataFrame cse = pd.DataFrame(cse_list) # 可根据需要导出为csv cse.to_csv("sri_lanka_stocks.csv", index=False, encoding="utf-8-sig")
内容的提问来源于stack exchange,提问作者Snyder Fox
相关产品推荐
相关产品推荐

