使用bs4爬取YouTube趋势视频时find_all返回空列表,如何修复?
解决YouTube热门视频爬取返回空列表的问题
问题原因
- 动态内容渲染:YouTube的页面内容是通过JavaScript动态生成的,
requests.get()只能获取初始的静态HTML文档,此时视频对应的ytd-video-renderer元素还未被渲染出来,所以BeautifulSoup找不到目标元素。 - 反爬机制拦截:直接用
requests请求可能会被YouTube识别为非浏览器请求,返回的内容不完整或被限制。
解决方案
方法一:用Selenium模拟浏览器加载动态内容
Selenium可以模拟真实浏览器的行为,等待页面完全加载后再获取源码,这样就能拿到包含视频元素的完整HTML。
- 先安装依赖:
pip install selenium
同时需要下载对应浏览器的驱动(比如ChromeDriver,要和你的Chrome版本匹配),并配置到系统路径中。
- 示例代码:
from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 初始化Chrome浏览器驱动 driver = webdriver.Chrome() driver.get("https://www.youtube.com/feed/explore") # 等待页面加载完成,确保目标元素出现 try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, "ytd-video-renderer")) ) time.sleep(2) # 额外等待确保内容加载完全 page_source = driver.page_source soup = BeautifulSoup(page_source, "lxml") trendings = soup.find_all("ytd-video-renderer", attrs={"class": "style-scope ytd-expanded-shelf-contents-renderer"}) print(f"找到{len(trendings)}个热门视频") # 遍历输出视频标题 for video in trendings: title = video.find("yt-formatted-string", id="video-title") if title: print(title.text.strip()) finally: driver.quit() # 关闭浏览器
方法二:使用YouTube Data API(更合规)
直接爬取YouTube网页可能违反其服务条款,使用官方API是更稳妥的方式,还能获取结构化的视频数据。
- 准备工作:
- 前往Google Cloud控制台创建项目,启用YouTube Data API v3,生成专属API密钥。
- 确保已安装requests:
pip install requests
- 示例代码:
import requests API_KEY = "你的API密钥" # 获取美国地区热门视频,可修改regionCode参数切换地区(如CN代表中国) url = f"https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&chart=mostPopular®ionCode=US&maxResults=20&key={API_KEY}" response = requests.get(url) if response.status_code == 200: data = response.json() for item in data["items"]: title = item["snippet"]["title"] view_count = item["statistics"]["viewCount"] print(f"标题:{title},播放量:{view_count}") else: print(f"请求失败,状态码:{response.status_code}")
原代码的小问题
soup.prettify()只是格式化HTML内容,不会修改原soup对象,这行代码可以直接去掉,不影响结果。- 即使静态HTML里存在目标元素,类名也可能随YouTube页面更新而变化,但核心问题还是动态加载导致的元素缺失。
内容的提问来源于stack exchange,提问作者Dilara
相关产品推荐
相关产品推荐

