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

Python网页抓取黄金价格遇问题:抓取HTML与页面不一致

解决网页抓取黄金价格的问题

问题1:抓取的HTML与浏览器不一致

网站的黄金价格数据大概率是通过JavaScript动态加载的,requests只能获取服务器返回的静态HTML,而浏览器会执行JS渲染出最终页面,所以两者内容存在差异。你可以通过以下两种方式解决:

方式1:从静态HTML的脚本标签提取数据

部分网站会把动态数据嵌入到静态HTML的script标签中(以JSON格式存储),可以直接解析这些内容:

import requests
from bs4 import BeautifulSoup
import json

url = "https://goldprice.org/"
req = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})
soup = BeautifulSoup(req.text, "html.parser")

# 遍历所有JSON格式的script标签
for script in soup.find_all('script', type='application/json'):
    try:
        data = json.loads(script.string)
        # 搜索包含价格、涨跌幅的字段(可根据实际输出调整)
        if any(key in data for key in ['price', 'change', 'gold']):
            print("提取到的价格相关数据:", data)
    except json.JSONDecodeError:
        continue

方式2:用Selenium渲染动态页面

如果静态HTML里完全没有目标数据,就用Selenium模拟浏览器加载页面,获取渲染后的完整HTML:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

# 配置无头浏览器(不弹出窗口)
options = Options()
options.add_argument('--headless=new')
driver = webdriver.Chrome(options=options)
driver.get("https://goldprice.org/")

# 等待页面加载完成
driver.implicitly_wait(5)

# 解析渲染后的页面
soup = BeautifulSoup(driver.page_source, "html.parser")
# 根据页面实际元素定位(需自己查看浏览器开发者工具获取类名/ID)
price = soup.find('div', class_='text-xl font-bold')  # 示例类名,需替换为真实属性
change = soup.find('span', class_='price-change')

if price:
    print("黄金价格:", price.text.strip())
if change:
    print("涨跌幅:", change.text.strip())

driver.quit()

问题2:自定义SearchSoup函数的KeyError

你出现KeyError: 0是因为错误地把soup对象当成列表用数字索引访问(soup[i])。BeautifulSoup的soup是文档根节点对象,并非列表,不能通过数字索引直接获取内容。正确的元素查找方式应该用:

  • soup.find():定位第一个匹配的元素
  • soup.find_all():获取所有匹配的元素
  • 通过标签名、类名、ID等属性筛选,比如soup.find('span', id='gold-price')

放弃自己写的索引遍历逻辑,用BeautifulSoup原生的查找方法就能避免这类错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:50:02