如何爬取YouTube指定频道下的全部视频数据?
问题根因
你写的代码只能拿到30条视频,是因为YouTube频道视频页用了无限滚动懒加载逻辑:页面初始只渲染首批30条视频,剩下的内容需要用户滚动到页面底部才会异步加载下一批。你的代码只执行了1次滚动操作,没有持续触发后续内容加载,自然拿不到全量数据。
可行解决方案
方案1:改造现有Selenium逻辑,循环滚动触发全量加载
核心思路是反复执行滚动到底部的操作,每次滚动后等待新内容加载完成,对比当前已加载的视频总数和上一轮的总数,如果连续两次滚动后总数没有变化,说明已经加载到频道最底部的所有视频,此时再提取数据即可。
修改后的可直接运行的代码如下:
import time from selenium import webdriver from selenium.webdriver.common.by import By # 配置待采集的频道ID列表 channels = [ 'pontodokaraoke' ] driver = webdriver.Chrome() for channel in channels: driver.get(f'https://www.youtube.com/c/{channel}/videos?view=0&sort=p&flow=grid') # 等待初始页面加载完成 time.sleep(3) last_count = 0 # 滚动后等待加载的时长,网络较差时可以调大到3-5秒 scroll_wait = 2 while True: # 滚动到当前页面最底部 driver.execute_script('window.scrollTo(0, document.body.scrollHeight)') time.sleep(scroll_wait) # 统计当前已加载的视频数量 current_titles = driver.find_elements(By.ID, "video-title") current_count = len(current_titles) # 数量不再增长说明没有更多内容,退出滚动循环 if current_count == last_count: break last_count = current_count # 提取全量视频信息 print(f"===== 频道{channel}视频列表,共{current_count}条 =====") for title in current_titles: info = title.get_attribute("aria-label") if info: print(info) driver.quit()
使用注意点:
- 如果运行时发现还是漏了视频,直接把
scroll_wait参数调大,本质是给页面留足加载新内容的时间,避免还没加载完就判定为到了底部 - 多频道采集只需要把频道ID依次加到
channels列表里即可,代码会自动遍历采集 - 链接里的
sort=p是按播放量排序,要按最新发布排序改成sort=dd,按最早发布排序改成sort=da - 如果触发了人机验证,手动完成验证后代码会继续执行,用已登录YouTube的浏览器配置启动Selenium能大幅降低验证触发概率
方案2:更高效率的采集方式
如果不想依赖页面渲染、模拟滚动,可以直接对接YouTube官方的视频列表查询接口,分页拉取频道下的所有视频数据,不需要加载页面元素,采集速度是Selenium方案的数倍,稳定性也更高,不会受页面改版、加载超时的影响。
内容的提问来源于stack exchange,提问作者Mateus Silva Alvarenga
相关产品推荐
相关产品推荐

