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

页面需两次加载完成,如何用BeautifulSoup抓取目标数据?

问题:抓取需二次渲染页面的目标元素

我尝试抓取页面https://toptees.store/linux-funny-cloud-computing中包含sold文本的<span>元素,但该网站需要两次加载才能完成页面渲染,导致数据无法被抓取。

尝试过的代码

1. requests + BeautifulSoup

import requests
from bs4 import BeautifulSoup
url = "https://toptees.store/linux-funny-cloud-computing"

reqs = requests.get(url)
soup = BeautifulSoup(reqs.text, 'lxml')
sold = soup.find_all("span", class_='ng-binding')
print(sold)

2. Selenium + BeautifulSoup

import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))  # ,options=options

filepath = 'urls.txt'
with open(filepath) as f:
    urls = [i.strip() for i in f.readlines()]

titles = []
for url in urls:
    driver.get(url)
    driver.maximize_window()
    time.sleep(3)
    soup = BeautifulSoup(driver.page_source, 'lxml')
    sold = soup.find('span', class_="ng-binding")
    print(sold)

上述代码的输出均为[],请问如何使用BeautifulSoup成功抓取该页面的目标数据?


解决方案

核心原因

该网站基于AngularJS开发(从ng-binding类可判断),目标数据是通过异步请求动态加载后二次渲染的:

  • requests只能获取初始静态HTML,拿不到异步加载的内容;
  • 固定time.sleep(3)的Selenium代码可能等待时间不足,或者没有精准定位到目标元素。

方案1:优化Selenium + BeautifulSoup(推荐)

用显式等待替代固定睡眠,精准等待目标元素渲染完成,再解析页面:

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

filepath = 'urls.txt'
with open(filepath) as f:
    urls = [i.strip() for i in f.readlines()]

for url in urls:
    driver.get(url)
    driver.maximize_window()
    try:
        # 最多等待10秒,直到包含'sold'文本的span元素出现
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, "//span[contains(text(), 'sold')]"))
        )
        # 解析页面并过滤目标元素
        soup = BeautifulSoup(driver.page_source, 'lxml')
        sold_spans = soup.find_all(
            "span", 
            class_='ng-binding', 
            string=lambda text: text and 'sold' in text.lower()
        )
        print("找到目标元素:", sold_spans)
        # 提取文本内容
        for span in sold_spans:
            print(span.get_text(strip=True))
    except Exception as e:
        print(f"加载超时或未找到元素: {str(e)}")

driver.quit()

关键改进点:

  1. 显式等待:动态等待元素出现,比固定睡眠更可靠,适配不同网络速度;
  2. 精准过滤:同时用class_和文本内容过滤,避免匹配无关的ng-binding元素;
  3. 异常捕获:处理加载超时情况,避免程序崩溃。

方案2:直接抓取数据接口(效率更高)

如果不想用Selenium渲染页面,可以通过浏览器开发者工具(F12)的Network面板,找到返回销量数据的异步接口(通常是XHR/Fetch请求),直接用requests请求接口获取数据:

import requests

# 需替换为实际抓包得到的接口地址
api_url = "https://toptees.store/api/product/linux-funny-cloud-computing"
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"
}

response = requests.get(api_url, headers=headers)
if response.status_code == 200:
    product_data = response.json()
    # 需根据实际接口返回的字段名调整
    sold_count = product_data.get('sold')
    print(f"{sold_count} sold")
else:
    print("请求接口失败")

说明:

  • 接口地址和字段名需要自己抓包确认,不同网站的接口规则不同;
  • 这种方式不需要渲染页面,速度远快于Selenium,但需要一定的抓包基础。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:55:22