使用Python和BeautifulSoup抓取同表格多页数据遇问题求助
问题分析与解决方案
1. 分页URL参数错误
你第一个代码里的start=-{page}是核心错误,Yahoo Finance的分页参数start应该是正整数,代表起始条目索引:
- 第一页:
start=0&count=25 - 第二页:
start=25&count=25 - 以此类推,所以循环里的URL应该改成:
另外注意url = f'https://finance.yahoo.com/markets/stocks/most-active/?start={page}&count=25'BeautifulSoup初始化时的解析器,你写的是'html',应该改成标准的'html.parser'或者'lxml'。
2. 动态加载数据无法通过直接修改count获取
你尝试用count=203获取全部数据失败,是因为该页面的表格数据是JavaScript动态加载的:requests只能获取页面初始HTML,而后续数据是在页面加载后通过AJAX请求获取的,直接修改URL参数不会触发JS加载更多内容。
解决方法有两种:
方法一:抓取后台API接口
打开浏览器开发者工具(F12),切换到Network标签页,滚动页面或点击分页,观察XHR/fetch请求,会发现Yahoo Finance实际是调用接口获取JSON格式的数据。直接请求这类接口就能拿到结构化数据,无需解析HTML,效率更高。示例代码:
import requests import json headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } all_data = [] for start in range(0, 201, 25): url = f'https://query1.finance.yahoo.com/v1/finance/screener/predefined/saved?formatted=true&lang=en-US®ion=US&scrIds=most_actives&count=25&start={start}' response = requests.get(url, headers=headers) data = json.loads(response.text) # 解析JSON中的股票数据 for item in data['finance']['result'][0]['quotes']: stock_info = { 'Symbol': item['symbol'], 'Name': item['shortName'], 'Price': item['regularMarketPrice'], 'Change': item['regularMarketChange'], 'Change%': item['regularMarketChangePercent'], 'Volume': item['regularMarketVolume'] # 其他字段可根据需求从JSON中提取 } all_data.append(stock_info) # 处理数据 print(len(all_data))
方法二:用Selenium模拟浏览器加载
如果不想分析API,可以用Selenium模拟浏览器滚动或点击分页按钮,等待页面加载完成后再抓取数据。示例代码:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time driver = webdriver.Chrome() driver.get('https://finance.yahoo.com/markets/stocks/most-active/') # 滚动页面加载全部数据 last_height = driver.execute_script("return document.body.scrollHeight") while True: driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(3) new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height # 抓取表格数据 tbody = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'tbody'))) rows = tbody.find_elements(By.CLASS_NAME, 'yf-1dbt8wv') all_data = [] for row in rows: cells = row.find_elements(By.CLASS_NAME, 'cell') line = [cell.text.strip() for cell in cells] splitter = line[0].split(" ", 1) line = splitter + line[1:] line[1] = line[1].strip() line[2] = line[2].split(" ", 1)[0] all_data.append(line) driver.quit() print(len(all_data))
你需要补充学习的内容
- 网络请求分析:学会用浏览器开发者工具抓包,识别动态页面的后台API接口,这是高效爬取动态数据的核心技能。
- 动态页面爬取技术:区分静态HTML爬取和动态JS渲染页面的爬取差异,掌握API请求、Selenium/Playwright等工具的使用。
- 反爬策略应对:Yahoo Finance会对请求进行验证,需要设置合理的
User-Agent、请求间隔,避免被封禁。 - 数据解析方式:学会处理JSON格式数据,相比HTML解析更高效可靠。
内容的提问来源于stack exchange,提问作者chik0di
相关产品推荐
相关产品推荐

