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

使用Scrapy爬取YouTube频道无法获取订阅数等目标数据求助

Scrapy爬取YouTube频道订阅数匹配失败原因及解决方法

核心原因

你用默认fetch拿到的响应根本不包含#subscriber-count对应的DOM节点:

  • YouTube全站是JavaScript动态渲染的,Scrapy默认的请求只下载初始静态HTML骨架,不会执行页面里的JS代码,你在浏览器开发者工具里看到的带订阅数的DOM,是浏览器跑完JS、拉完接口数据之后动态插进去的,初始静态页里根本没有这个元素,XPath、CSS选择器当然匹配不到。
  • Scrapy默认请求头携带的UA带有明显的爬虫标识,直接请求很容易被YouTube的反爬策略拦截,返回的要么是验证页,要么是不包含完整数据的空壳页面。

你可以先在Scrapy shell里执行view(response),会直接打开Scrapy拿到的本地响应文件,一眼就能看到页面根本没有加载出正常的频道内容。

可行解决方案

方案1:对接浏览器渲染组件(最稳,新手不容易出错)

用scrapy-playwright对接无头浏览器,让请求像真实用户访问一样等页面JS跑完、目标元素加载完成之后再做解析,不需要额外找内嵌数据的路径。

  1. 先安装依赖:
pip install scrapy-playwright
playwright install chromium
  1. 在项目settings.py里加配置:
DOWNLOAD_HANDLERS = {
    "http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
    "https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
}
TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
  1. 写请求的时候加等待规则,等订阅数节点加载出来再返回响应:
yield Request(
    url="https://www.youtube.com/c/JohnWatsonRooney",
    meta={
        "playwright": True,
        "playwright_page_methods": [
            # 等待目标元素加载,超时时间设10秒
            {"method": "wait_for_selector", "args": ["#subscriber-count"], "timeout": 10000}
        ]
    },
    callback=self.parse
)

之后再用你之前写的XPathresponse.xpath('//*[@id="subscriber-count"]/text()').get()就能拿到订阅数了。
注意:首次访问大概率会弹出Cookie同意框,可以在page_methods里加个点击同意按钮的步骤,避免卡在弹窗导致元素加载失败。

方案2:提取静态页内嵌的初始数据(速度快,不需要浏览器)

YouTube会把所有页面核心数据打包塞到初始HTML的ytInitialData全局JS变量里,不需要渲染就能直接提取,请求速度比开浏览器快很多。
解析参考代码:

import re
import json

def parse(self, response):
    # 正则匹配内嵌的JSON数据
    data_pattern = re.compile(r'var ytInitialData = ({.*?});', re.S)
    match_result = data_pattern.search(response.text)
    if match_result:
        page_data = json.loads(match_result.group(1))
        # 顺着JSON结构逐层查找,订阅数字段在header对应的频道元数据里,字段名是subscriberCountText
        # 初次调试可以先print(page_data),逐层定位路径即可,不需要依赖DOM节点

这个方案的缺点是如果YouTube调整了页面结构、改了变量名,就要重新匹配解析规则。

避坑提醒

  • 不要直接复制浏览器开发者工具里的XPath/CSS选择器就往Scrapy里用,浏览器里的DOM是JS执行完成后的结果,和Scrapy默认拿到的静态响应DOM结构差异很大,直接用大概率选不到内容。
  • 不要用Scrapy默认的UA发请求,最好在settings里配置成真实浏览器的UA,减少被反爬拦截的概率。

内容的提问来源于stack exchange,提问作者ben mansour mahdi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:00:59