如何在JoinQuant平台用Selenium/BeautifulSoup抓取表格转DataFrame?
问题:抓取东方财富网高管表格并转为DataFrame
目标是抓取https://data.eastmoney.com/executive/000001.html中滚动可见的大型表格,将其转为Python的DataFrame,纠结选用BeautifulSoup还是Selenium,过程中遇到以下问题:
尝试Selenium的问题
看到Stack Overflow有说法称BeautifulSoup无法抓取网页表格数据,于是编写Selenium代码:
driver = webdriver.Chrome() driver.get('https://data.eastmoney.com/executive/000001.html') table_element = driver.find_element_by_xpath("//table") item_element = table_element.find_element_by_xpath("//tr[2]/td[3]") item_text = item_element.text df = pd.DataFrame([item_text], columns=["Item"]) print(df) driver.quit()
运行后报错,提示chromedriver需在PATH中。由于使用在线回测平台JoinQuant,无法配置本地驱动路径,Selenium无法继续使用。
尝试BeautifulSoup的问题
改用BeautifulSoup编写代码:
# Web Crawler # Sent HTTP Request to get Internet content url = 'https://data.eastmoney.com/executive/000001.html' response = requests.get(url) html_content = response.text # Check if the request is successful if response.status_code == 200: # Use BeautifulSoup to Analyze Internet information and get the table soup = BeautifulSoup(html_content, 'html.parser') table = soup.find_all('table') # Acquire the rows and columns of the table rows = table.find_all('tr') data = [] for row in rows: cols = row.find_all('td') row_data = [] for col in cols: row_data.append(col.text.strip()) data.append(row_data) else: print("Failed to Retrieve the Webpage.") # Set up DataFrame dataframe = pd.DataFrame(data) # Print DataFrame print(dataframe)
运行后触发AttributeError,提示ResultSet对象无find_all方法;将find_all('table')改为find('table')后,又出现'NoneType' object has no attribute 'find_all'的报错。
疑问
应该选择Selenium还是BeautifulSoup?或是其他工具?该如何解决当前问题?
解决方案
核心原因:表格数据为异步加载,静态HTML中不存在
该页面的高管表格并非直接嵌入静态HTML,而是通过JavaScript异步请求后端接口获取数据后渲染的。因此直接用requests+BeautifulSoup抓取静态HTML无法获取表格内容;而Selenium依赖本地驱动,在线平台无法支持,最优方案是直接抓取数据接口。
具体实现步骤
- 定位数据接口:打开浏览器开发者工具(F12),切换至「Network」标签,刷新页面后筛选「XHR」类型请求,找到返回高管数据的接口(该页面的接口格式类似
https://datacenter.eastmoney.com/securities/api/data/v1/get?sortColumns=SECUCODE,STARTDATE&sortTypes=1,-1&pageSize=50&pageNumber=1&reportName=RPT_EXECUTIVE_INFO&columns=ALL&filter=(SECUCODE%3D%22000001%22))。 - 请求接口并解析数据:用
requests请求接口,解析返回的JSON数据后直接转为DataFrame。
适配JoinQuant的示例代码
import requests import pandas as pd def get_executive_data(stock_code): # 构造请求URL,替换stock_code即可获取对应股票的高管数据 url = f"https://datacenter.eastmoney.com/securities/api/data/v1/get?sortColumns=SECUCODE,STARTDATE&sortTypes=1,-1&pageSize=100&pageNumber=1&reportName=RPT_EXECUTIVE_INFO&columns=ALL&filter=(SECUCODE%3D%22{stock_code}%22)" # 配置请求头模拟浏览器,避免被拦截 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" } response = requests.get(url, headers=headers) # 处理JSONP格式的返回数据,剥离jQuery回调包裹 json_str = response.text.lstrip("jQuery").split("(")[1].rstrip(");") # 解析JSON并提取数据 data_result = pd.read_json(json_str)["result"]["data"] # 转为DataFrame df = pd.DataFrame(data_result) return df # 获取000001的高管数据 executive_df = get_executive_data("000001") print(executive_df.head())
对之前BeautifulSoup错误的解释
soup.find_all('table')返回的是ResultSet对象(即表格列表),无法直接调用find_all('tr'),需遍历列表或取第一个元素;- 改为
find('table')后返回None,是因为静态HTML中根本不存在目标表格,表格是JS动态渲染生成的,所以找不到。
为什么不选Selenium?
JoinQuant等在线平台通常限制使用依赖本地驱动的浏览器自动化工具,且直接抓取数据接口的效率更高、稳定性更强。
内容的提问来源于stack exchange,提问作者Evariste Galois
相关产品推荐
相关产品推荐

