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

使用scraper crate爬取网站价格时解析出0₽的问题求助

解决网页动态价格爬取问题

问题原因

目标网站的价格数据是通过JavaScript动态渲染的。直接用reqwest获取的是服务器返回的初始HTML,此时价格字段还未被JS填充,所以显示为0 ₽;而浏览器会自动执行页面中的JS,从后端接口拉取真实价格并渲染到页面上,所以你能看到正常价格。

解决方案

方案1:使用Headless浏览器模拟渲染(适配复杂渲染场景)

通过调用Headless浏览器(如Chrome)执行页面JS,获取渲染后的完整HTML。可以用Rust的thirtyfour库(Selenium WebDriver绑定)实现:

首先在Cargo.toml中添加依赖:

[dependencies]
thirtyfour = "0.32"
tokio = { version = "1.0", features = ["full"] }
scraper = "0.18"

然后编写执行代码:

use thirtyfour::prelude::*;
use scraper::{Html, Selector};

#[tokio::main]
async fn main() -> WebDriverResult<()> {
    // 启动ChromeDriver(需提前安装ChromeDriver并配置到系统PATH)
    let caps = DesiredCapabilities::chrome();
    let driver = WebDriver::new("http://localhost:9515", caps).await?;

    // 访问目标页面
    driver.get("https://gosmoke.ru/zhidkosti").await?;
    
    // 等待价格元素加载完成(可根据页面加载速度调整等待逻辑)
    driver.wait().until(ElementLocated(By::Css("div.price>span"))).await?;

    // 获取渲染后的页面源码
    let html = driver.page_source().await?;
    let document = Html::parse_document(&html);

    // 解析商品名称与价格
    let name_selector = Selector::parse("div.caption-title>a").unwrap();
    let price_selector = Selector::parse("div.price>span").unwrap();

    let names = document.select(&name_selector).map(|e| e.inner_html());
    let prices = document.select(&price_selector).map(|e| e.inner_html().trim().to_string());

    // 对应打印商品与价格
    for (name, price) in names.zip(prices) {
        println!("{}: {}", name, price);
    }

    // 关闭浏览器
    driver.quit().await?;
    Ok(())
}

方案2:直接调用后端API(更高效)

打开浏览器开发者工具(F12),切换到「网络」标签页,刷新页面后筛选XHR/Fetch类型请求,找到网站加载价格数据的后端API接口。直接请求该接口获取结构化数据,无需解析HTML。

示例代码(假设找到的API接口为https://gosmoke.ru/api/products,需根据实际抓包结果调整):

use reqwest::Error;
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct Product {
    title: String,
    price: String,
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    let client = reqwest::Client::new();
    // 可能需要添加User-Agent等请求头模拟浏览器
    let response = client.get("https://gosmoke.ru/api/products")
        .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
        .send()
        .await?
        .json::<Vec<Product>>()
        .await?;

    for product in response {
        println!("{}: {}", product.title, product.price);
    }

    Ok(())
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:07:51