You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python的BeautifulSoup爬取带加载更多按钮的单页站点全部数据

爬取Carmax全量车辆列表解决方案

你当前的代码只能获取到页面初始加载的第一页数据,原因是该站点的车辆列表为动态加载内容:首次打开页面仅渲染前20条左右数据,后续数据需要点击「加载更多」按钮触发JS请求后端接口才能加载,静态requests请求无法直接拿到后续内容。

下面给出两种可行实现方案:

方案1:Selenium模拟人工点击加载(上手简单)

该方案通过浏览器自动化工具模拟用户点击操作,直到没有更多数据可加载后再统一解析内容,不需要分析站点接口逻辑。

依赖安装

执行以下命令安装所需工具:
pip install selenium webdriver-manager

示例代码

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
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import time

# 初始化Chrome浏览器
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get("https://www.carmax.com/cars/all")
# 等待页面初始加载完成
time.sleep(3)

# 循环点击加载更多按钮,直到按钮消失
while True:
    try:
        # 找到加载更多按钮
        load_more_btn = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'See More Matches')]"))
        )
        # 滚动到按钮位置再点击,避免被遮挡
        driver.execute_script("arguments[0].scrollIntoView();", load_more_btn)
        load_more_btn.click()
        # 等待新内容加载完成
        time.sleep(2)
    except:
        # 没有找到加载更多按钮,说明已经加载完全部内容
        break

# 解析全量页面内容
soup = BeautifulSoup(driver.page_source, 'html.parser')
tiles = soup.find_all('div', class_='car-tile')

n = 0
for tile in tiles:
    yearmake = tile.find('span', class_='year-make').text.strip()
    modeltrim = tile.find('span', class_='model-trim').text.strip()
    print('TILE ' + str(n) + ': ym=' + yearmake + ', mt=' + modeltrim)
    n = n + 1

driver.quit()

方案2:直接调用数据接口(性能更高)

如果不想启动浏览器,可以直接抓包拿到站点的车辆数据接口,循环请求接口拿到全量数据,请求速度更快也更稳定。
你可以通过浏览器F12控制台的「网络」面板筛选XHR请求,找到返回车辆列表数据的POST接口,自定义请求参数中的页码、每页数量,循环请求直到返回结果为空即可。

示例代码框架

import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36',
    'Content-Type': 'application/json'
}
url = "你抓包拿到的车辆数据接口地址"
page = 1
all_cars = []

while True:
    # 请求参数根据抓包结果调整
    payload = {
        "page": page,
        "perPage": 24,
        "sort": "year:desc"
        # 其他必填参数按照抓包内容补充
    }
    resp = requests.post(url, json=payload, headers=headers)
    data = resp.json()
    # 判断是否还有数据
    if not data.get('cars'):
        break
    all_cars.extend(data['cars'])
    page += 1

# 后续处理车辆数据即可
for n, car in enumerate(all_cars):
    print(f'TILE {n}: ym={car["yearMake"]}, mt={car["modelTrim"]}')

内容的提问来源于stack exchange,提问作者Bradley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 02:27:00