如何在Python BeautifulSoup代码中抓取网页表格的前10条数据
BSCscan代币持有者表格提取修正方案
存在的问题
- 元素选择错误:表格行
<tr>的子单元格是<td>标签,原代码错误使用row.find_all('tr')查找单元格,无匹配结果因此无表格输出 - 动态数据未适配:BSCscan的代币持有者列表为异步加载内容,直接请求代币主页面的静态HTML不含持有者表格数据,需调用对应的动态接口获取
- 表格定位方式不稳定:通过索引
[1]定位表格容错性极低,页面结构变动就会定位失败
修正后代码
from bs4 import BeautifulSoup import requests, random, re header = {"User-Agent": "Mozilla/5.0"} url = "https://bscscan.com/token/" suffix = "#balances" token = "0x8076c74c5e3f5852037f31ff0093eeb8c8add8d3" line = str(url) + str(token) + str(suffix) urlpage = requests.get(line, header) ca = BeautifulSoup(urlpage.content, 'html.parser') tokenholders = ca.find(id='ContentPlaceHolder1_tr_tokenHolders').get_text() totalholders = ((((tokenholders.strip()).strip("Holders:")).strip()).strip(" a ")).strip() caname = ca.find('span', class_='text-secondary small').get_text() def get_transfer_count(token:str)->str: with requests.Session() as s: s.headers = {'User-Agent':'Mozilla/5.0'} r = s.get(f'https://bscscan.com/token/{token}') pause = float(random.randint(10,100)) / 200 sid = re.search(r"var sid = '(.*?)'", r.text).group(1) r = s.get(f'https://bscscan.com/token/generic-tokentxns2?m=normal&contractAddress={token}&a=&sid={sid}&p=1') return re.search(r"var totaltxns = '(.*?)'", r.text).group(1) # 新增获取持有者列表的函数 def get_holders_list(token:str)->list: with requests.Session() as s: s.headers = {'User-Agent':'Mozilla/5.0'} r = s.get(f'https://bscscan.com/token/{token}') sid = re.search(r"var sid = '(.*?)'", r.text).group(1) # 请求持有者列表动态接口,p参数为页码,这里取第一页 r = s.get(f'https://bscscan.com/token/generic-tokenholders2?m=normal&a={token}&sid={sid}&p=1') soup = BeautifulSoup(r.text, 'html.parser') rows = soup.find('table').find_all('tr', limit=6) # 取前5条数据+表头 res = [] for row in rows[1:]: cols = [col.text.strip() for col in row.find_all('td')] # 按顺序取排名、地址、余额、占比、价值 res.append([cols[0], cols[1], cols[2], cols[3], cols[4]]) return res transfers = get_transfer_count(token) holders = get_holders_list(token) print (f"{caname}: {totalholders} -> {transfers}") print(line) # 输出表格内容 for item in holders: print(f"{item[0]} {item[1]} {item[2]} {item[3]} {item[4]}")
效果说明
运行后即可输出你需要的前5条持有者数据,包含排名、地址、代币余额、占比、美元估值,和预期输出格式一致。如果需要更多页数据,调整接口的p参数即可。
内容的提问来源于stack exchange,提问作者rbutrnz
相关产品推荐
相关产品推荐

