如何使用Scrapy爬取YouTube视频ID?不使用YouTube Data API的实现方案
问题解答
1. 不用YouTube Data API仅用Scrapy爬取是否可行?
可行,但要注意YouTube搜索结果页的内容几乎都是客户端JavaScript动态渲染的,直接通过普通HTTP请求拿到的初始静态HTML中不包含你需要的视频列表节点,这就是你拿到空列表的核心原因。
2. 你当前代码的问题
你虽然配置了scrapy-selenium中间件,但默认的start_urls发起的是普通Scrapy请求,不会触发Selenium渲染逻辑,拿到的依然是未加载JS的原始页面,自然无法匹配到动态生成的dismissible节点。
3. 修复方案
3.1 调整爬虫代码,使用SeleniumRequest发起请求
导入SeleniumRequest替换默认请求,强制触发页面渲染,同时增加等待时间确保元素加载完成,修改后的代码如下:
import scrapy from scrapy_selenium import SeleniumRequest class MoviesintheatersSpider(scrapy.Spider): name = 'MoviesInTheaters' allowed_domains = ['youtube.com'] def start_requests(self): yield SeleniumRequest( url='https://www.youtube.com/results?search_query=food+luck', # 等待3秒确保页面完全渲染 wait_time=3, callback=self.parse ) def parse(self, response): # 直接匹配所有id为thumbnail的a标签的href属性 thumb_hrefs = response.xpath('//a[@id="thumbnail"]/@href').getall() for href in thumb_hrefs: if '/watch?v=' not in href: continue # 提取视频ID,排除url后多余参数 video_id = href.split('v=')[-1].split('&')[0] yield { 'video_id': video_id }
3.2 调整Selenium配置适配新版Chrome
如果你使用的是Chrome 112及以上版本,将SELENIUM_DRIVER_ARGUMENTS修改为以下配置,避免旧版无头模式渲染异常:
SELENIUM_DRIVER_ARGUMENTS=['--headless=new', '--no-sandbox', '--disable-dev-shm-usage']
同时确保你安装的chromedriver版本和本地Chrome浏览器版本完全一致,否则会出现启动失败问题。
4. 额外注意事项
- 可以在settings中开启
DOWNLOAD_DELAY = 2,控制请求频率,避免触发YouTube反爬机制 - YouTube有较完善的反爬策略,大规模爬取可能会遇到验证码、IP封禁等问题,可根据需求搭配代理池、验证码识别工具使用
- 爬取行为需遵守YouTube的服务条款,避免违规商用或大规模抓取内容
内容的提问来源于stack exchange,提问作者Morton
相关产品推荐
相关产品推荐

