使用Python BeautifulSoup按列头正确抓取列数不一致的表格数据方案咨询
BscScan表格数据爬取优化方案
核心优化逻辑
不再硬编码td下标,先提取表格表头生成列名到下标的映射,后续所有行数据都通过列名取对应位置的值,彻底解决部分行列数不足、列顺序调整导致的提取错误问题。
主要优化点
- 修复原代码user-agent的语法错误,原列表存储的是字符串格式的header定义,无法直接传入请求
- 自动生成表头-索引映射,完全脱离硬编码下标依赖
- 增加行数据容错校验,缺失指定列的行自动跳过,不会抛出索引越界异常
- 统一数据提取逻辑,无需维护两套不同下标的提取分支
优化后完整代码
from bs4 import BeautifulSoup import re, random import requests # 修正user-agent定义,直接存储字典格式 user_agent_list = [ {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0'}, {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'}, {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15'}, {'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36'}, {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36'} ] header = random.choice(user_agent_list) trim = re.compile(r'[^\d,.]+') url = "https://bscscan.com/txsInternal?a=0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c&ps=100&p=1" reqblockdetails = requests.get(url, headers=header, timeout=10) soupblockdetails = BeautifulSoup(reqblockdetails.content, 'html.parser') table = soupblockdetails.find('table') # 第一步:生成表头到索引的映射 headers = [th.get_text(strip=True) for th in table.find('tr').find_all('th')] col_index = {col: idx for idx, col in enumerate(headers)} # 指定需要提取的列 target_cols = ['Parent Txn Hash', 'Type', 'From', 'To', 'Value'] # 第二步:遍历行提取数据 for row in table.find_all('tr')[1:101]: # 取前100行数据 tds = row.find_all('td') # 跳过跨列/列数不足的行 if len(tds) < len(headers): continue # 按列名提取对应值 try: ptxnhash = tds[col_index['Parent Txn Hash']].get_text(strip=True) exectype = tds[col_index['Type']].get_text(strip=True) source = tds[col_index['From']].get_text(strip=True) destination = tds[col_index['To']].get_text(strip=True) amount = trim.sub('', tds[col_index['Value']].get_text(strip=True)) # 过滤无效hash if not ptxnhash.startswith('0x'): continue print(f"{ptxnhash}\t{source}\t{destination}\t{amount}") except KeyError: # 缺少指定列直接跳过 continue
效果说明
输出格式与你原有的输出完全一致,同时只要网站表头不发生变化,就算后续调整列顺序、部分行列数缺失,都能稳定提取目标字段,容错性大幅提升。
内容的提问来源于stack exchange,提问作者rbutrnz
相关产品推荐
相关产品推荐

