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

为何Scrapy选择器仅获取父元素?Trezor页面爬取问题咨询

解决Scrapy选择器爬取Trezor币种页面只返回空tr标签的问题

我来帮你搞定这个爬取问题!先还原下你遇到的场景:

问题重现

你用requests获取Trezor币种页面的原始HTML,再用Scrapy选择器提取表格行时,只拿到了空的<tr>标签,代码和结果如下:

import requests
from scrapy.selector import Selector

req = requests.get('https://trezor.io/coins/').content
xs = '//*[@id="content"]/tr'
sel = Selector(text=req).xpath(xs)
print(sel.extract_first())
# 输出: '<tr class="coin " data-href="./#BTC" id="BTC"></tr>'

而爬维基百科静态页面时却能正常获取到完整元素内容,这确实让人摸不着头脑。

问题根源

核心原因是Trezor的币种表格是动态加载的:

  • 服务器返回的原始HTML里,只有空的<tr>框架,里面的<td>内容是页面加载完成后,通过JavaScript从后端接口拉取数据并渲染出来的。
  • requests.get只能拿到服务器返回的初始静态HTML,不会执行页面的JavaScript,所以看不到渲染后的<td>元素。
  • 维基百科的内容是直接嵌入在静态HTML里的,所以能直接爬取到完整内容。

解决方案

有两种高效的解决方法,你可以根据需求选择:

方法1:用Scrapy集成JS渲染工具(推荐)

可以使用scrapy-playwright让Scrapy模拟浏览器渲染页面,等待JS执行完成后再爬取内容。

  1. 先安装依赖:
pip install scrapy-playwright
playwright install chromium
  1. 在Scrapy项目的settings.py里配置:
DOWNLOAD_HANDLERS = {
    "http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
    "https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
}

PLAYWRIGHT_LAUNCH_OPTIONS = {
    "headless": True,  # 无头模式,不显示浏览器窗口
    "timeout": 30000,
}
  1. 编写爬虫代码:
import scrapy
from scrapy_playwright.page import PageCoroutine

class TrezorCoinsSpider(scrapy.Spider):
    name = "trezor_coins"
    start_urls = ["https://trezor.io/coins/"]

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(
                url,
                meta={
                    "playwright": True,
                    # 等待表格内容加载完成
                    "playwright_page_coroutines": [
                        PageCoroutine("wait_for_selector", "tr.coin td"),
                    ],
                },
            )

    def parse(self, response):
        # 现在可以正常提取所有<tr>里的<td>内容了
        for row in response.xpath('//*[@id="content"]/tr[not(@class="header")]'):
            yield {
                'coin_id': row.xpath('./@id').get(),
                'full_name': row.xpath('./td[1]/text()').get().strip(),
                'symbol': row.xpath('./td[2]/text()').get().strip(),
                'type': row.xpath('./td[3]/text()').get().strip(),
                'support_status': row.xpath('./td[4]/text()').get().strip(),
                'segwit_support': row.xpath('./td[5]/text()').get().strip(),
                'notes': row.xpath('./td[6]/text()').get().strip() if row.xpath('./td[6]/text()').get() else ''
            }

方法2:直接爬取后端API(更高效)

打开浏览器开发者工具的「Network」标签,刷新页面后可以找到加载币种数据的API接口,直接请求这个接口获取JSON格式的数据,比爬页面更简单高效:

import requests

# 通过浏览器开发者工具找到加载币种数据的API接口地址
api_url = "你找到的API接口地址"
response = requests.get(api_url)
coins_data = response.json()

# 遍历提取数据
for coin in coins_data:
    print(f"币种名称: {coin['name']}, 符号: {coin['symbol']}, 支持状态: {coin['support']}")

这样就能轻松获取到所有币种的完整数据啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:42:51