抓取动态网站

动态网站在初始页面加载后使用 JavaScript 加载内容。本指南介绍如何使用 FourA 的浏览器 endpoint 从这些站点收集数据。

问题

当您向重度依赖 JavaScript 的网站发送标准的 HTTP request 时,您得到的是 HTML 外壳,而不是实际内容。您需要的数据(产品列表、价格、搜索结果)是在页面在浏览器中渲染后由 JavaScript 加载的。

这在使用 React, Vue, Angular 和 Next.js 等现代框架中越来越常见。

解决方案:浏览器 request

FourA 的浏览器 endpoint (POST /api/browser/) 会在 Chrome 浏览器实例中打开您的 URL,并且会:

  1. 加载页面
  2. 执行所有 JavaScript
  3. 等待内容渲染
  4. 返回完整渲染的 HTML

第 1 步:确定您的需求

在发出 request 之前,请在浏览器中访问目标页面并使用 DevTools (F12) 查找确认内容已加载的文本或元素。例如:

  • 在 JS 渲染后出现的产品名称
  • 渲染后的 HTML 中类似 product-grid 的 CSS 类
  • 仅在数据加载时才出现的诸如 "results" 之类的文本字符串

第 2 步:发送浏览器 request

curl -X POST https://eu.api.foura.ai/api/browser/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
  }'

checkText 选项指示 FourA 验证渲染后的页面中是否出现字符串 "product-grid"。如果该字符串在超时前未出现,请求将失败,以此告知您内容未加载。

第 3 步:解析 HTML

响应的 body 字段包含完全渲染的 HTML。请使用您偏好的库进行解析:

Python (BeautifulSoup)

import requests
from bs4 import BeautifulSoup

resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}, json={
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
})

html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")

for product in soup.select(".product-card"):
    name = product.select_one(".product-name").text.strip()
    price = product.select_one(".product-price").text.strip()
    print(f"{name}: {price}")

Node.js (cheerio)

import * as cheerio from 'cheerio';

const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com/products',
    timeout_ms: 15000,
    checkText: 'product-grid'
  })
});

const { body: html } = await resp.json();
const $ = cheerio.load(html);

$('.product-card').each((i, el) => {
  console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});

故障排除

仍然获取到空内容?

  • 确认页面确实使用了 JavaScript 渲染(对比“查看网页源代码”与 DevTools 的结果)
  • 增加 timeout_ms:有些页面加载较慢
  • 检查页面是否需要身份验证或 cookie(使用 cookies 参数)

遇到 CAPTCHA 页面?

  • 对于单一/HTTP 请求,请切换至 proxy endpoint (POST /api/proxy/) 以自动轮换 IP。
  • 要通过 proxy 路由浏览器请求,请传递浏览器 endpoint 的 proxy 参数。proxy endpoint 仅包装单一/HTTP 请求,不包括浏览器请求。

proxy 参数接受早期 response 返回的不透明 proxy ID,绝对不能使用您自己的 proxy 地址。请先运行一次 POST /api/proxy/(或 POST /api/auto/)调用,读取其返回的 proxy 字段,然后将其固定:

# Step 1: let FourA find a working exit. The response carries "proxy": "A1B2C3".
curl -X POST "https://eu.api.foura.ai/api/proxy/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"maxTries": 5, "request": {"method": "GET", "url": "https://example.com/products"}}'

# Step 2: render through that same exit.
curl -X POST "https://eu.api.foura.ai/api/browser/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/products", "proxy": "A1B2C3", "timeout_ms": 20000}'

发送地址而不是 ID 会返回 400 Invalid proxy format。完整模式请参阅 在多个请求中重用 proxy

后续步骤

更新于: 2026年8月12日