使用BeautifulSoup4无法抓取网站表格?代码运行无数据求解决
问题分析
你遇到的核心问题是:目标网站的表格数据是动态加载的。requests.get()只能获取页面初始的静态HTML源码,而实际表格内容是页面加载完成后通过JavaScript发起AJAX请求异步获取的,所以静态源码里根本没有你要找的table元素,自然返回空结果。
解决方案
方法1:直接请求AJAX接口(推荐,效率更高)
通过浏览器开发者工具抓包,可以找到加载表格数据的API接口,直接请求该接口获取JSON格式的数据,再转换为DataFrame。
代码示例
import requests import pandas as pd # 数据接口地址 api_url = "https://www.sfda.gov.sa/api/Cosmetics/GetCosmeticsList" # 请求参数(从浏览器开发者工具的Network面板复制) payload = { "draw": 1, "columns": [ {"data": "ProductName", "name": "", "searchable": True, "orderable": True, "search": {"value": "", "regex": False}}, {"data": "CategoryName", "name": "", "searchable": True, "orderable": True, "search": {"value": "", "regex": False}}, {"data": "CountryName", "name": "", "searchable": True, "orderable": True, "search": {"value": "", "regex": False}}, {"data": "CompanyName", "name": "", "searchable": True, "orderable": True, "search": {"value": "", "regex": False}} ], "order": [{"column": 0, "dir": "asc"}], "start": 0, "length": 10000, # 设置足够大的数值获取更多数据,默认每页10条 "search": {"value": "", "regex": False}, "language": "en" } # 请求头,模拟浏览器请求 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", "X-Requested-With": "XMLHttpRequest" } # 发送POST请求获取数据 response = requests.post(api_url, json=payload, headers=headers) data = response.json() # 转换为DataFrame并调整列名 df = pd.DataFrame(data["data"]) df.rename( columns={ "CategoryName": "Category", "CountryName": "Country", "CompanyName": "Company" }, inplace=True ) print(df)
方法2:用Selenium模拟浏览器渲染
如果不想分析AJAX接口,可以用Selenium驱动浏览器加载页面,等待JavaScript渲染完成后再抓取页面内容。
代码示例
from bs4 import BeautifulSoup import pandas as pd from selenium import webdriver from selenium.webdriver.chrome.options import Options import time # 配置Chrome无头模式(不显示浏览器窗口) chrome_options = Options() chrome_options.add_argument("--headless=new") chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("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") # 初始化浏览器驱动 driver = webdriver.Chrome(options=chrome_options) driver.get("https://www.sfda.gov.sa/en/cosmetics-list") # 等待页面渲染完成(可根据网络情况调整等待时间) time.sleep(3) # 获取渲染后的页面源码 soup = BeautifulSoup(driver.page_source, "html.parser") driver.quit() # 提取表格数据 table = soup.find("table", attrs={"class": "table table-striped display"}) if table: table_rows = table.find_all("tr") res = [] for tr in table_rows: td = tr.find_all("td") row = [cell.text.strip() for cell in td if cell.text.strip()] if row: res.append(row) df = pd.DataFrame(res, columns=["ProductName", "Category", "Country", "Company"]) print(df) else: print("未找到目标表格元素")
注意事项
- 方法1需要注意接口参数可能会随网站更新变化,若出现请求失败,需重新抓包确认参数。如果要获取全量数据,需要处理分页逻辑(调整
start和length参数循环请求)。 - 方法2需要安装Selenium库和对应浏览器的驱动(如ChromeDriver),运行效率略低于方法1,但无需分析接口。
内容的提问来源于stack exchange,提问作者Lucidity
相关产品推荐
相关产品推荐

