爬取ENR网站建筑成本指数表格报AttributeError错误求助
解决ENR网站爬取表格时的AttributeError问题
问题本质
你碰到的AttributeError: 'NoneType' object has no attribute 'find_all',核心是soup.find('table')返回了None——也就是请求回来的页面里根本找不到目标表格。结合之前代码能正常运行现在失效的情况,基本可以确定是网站服务器升级了反爬策略,拦截了你的无标识爬虫请求,返回的不是包含表格的正常页面。
修复方案及代码调整
针对这个问题,从三个关键方向修改代码:
添加请求头模拟浏览器
服务器会通过请求头识别请求来源,给requests.get带上标准的浏览器请求头,避免被直接判定为爬虫。增加请求状态校验
先检查请求是否成功(状态码200),避免后续处理无效页面。增加空值判断
在操作表格对象前先判断是否存在,防止直接调用方法报错。
修改后的代码:
import requests from bs4 import BeautifulSoup import pandas as pd def web_scraper(url): # 模拟浏览器请求头,可替换成你自己浏览器的User-Agent(在浏览器开发者工具中可查看) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept-Language': 'zh-CN,zh;q=0.9' } # 发送请求并校验状态 page = requests.get(url, headers=headers) if page.status_code != 200: print(f"请求失败,状态码:{page.status_code}") return None # 解析页面 soup = BeautifulSoup(page.text, 'lxml') table1 = soup.find('table') # 检查表格是否存在 if not table1: print("页面中未找到目标表格,可能被反爬拦截") return None # 提取表头 headers = [] for i in table1.find_all('th'): title = i.text.strip() headers.append(title) # 填充数据到DataFrame df = pd.DataFrame(columns=headers) for j in table1.find_all('tr')[1:]: row_data = j.find_all('td') row = [i.text.strip() for i in row_data] if row: # 跳过空行 df.loc[len(df)] = row return df # 调用函数 result_df = web_scraper('https://www.enr.com/economics/historical_indices/construction_cost_index_history') if result_df is not None: print(result_df.head())
额外提醒
- 如果加了请求头还是拿不到表格,说明网站可能用JavaScript动态加载数据,这时得改用
selenium或playwright模拟真实浏览器加载页面后再提取数据。 - 不要频繁发送请求,避免触发更严格的反爬限制,可适当加请求间隔(比如
time.sleep(2))。
内容的提问来源于stack exchange,提问作者jaralepi
相关产品推荐
相关产品推荐

