Flask中使用BeautifulSoup爬取YouTube报错:NoneType无text属性
AttributeError: 'NoneType' object has no attribute 'text' 问题解决
问题根源
你代码里的soup.find(class_='style-scope ytd-rich-grid-media')返回了None,说明BeautifulSoup没找到对应的元素,后续调用.text自然会报错。主要原因有两个:
- 页面动态渲染:YouTube首页的视频卡片是通过JavaScript动态加载的,
requests.get()只能拿到静态HTML源码,动态生成的内容不会包含在响应里。 - 选择器无效:
style-scope ytd-rich-grid-media是通用类名,不是定位视频标题的精准选择器,而且YouTube的类名经常变动,甚至包含随机字符。
解决办法
方法一:用Selenium处理动态页面
Selenium可以模拟浏览器加载页面,能获取到动态渲染后的完整内容。步骤如下:
- 安装依赖:
pip install selenium
- 下载对应浏览器的驱动(比如ChromeDriver,需和浏览器版本匹配),放到项目目录或系统PATH中。
- 修改爬虫函数:
import requests from flask import Blueprint, render_template from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service import time views = Blueprint('views', __name__) def scrapper(): # 配置Chrome驱动路径,替换为你实际的路径 service = Service(executable_path='./chromedriver') driver = webdriver.Chrome(service=service) driver.get('https://www.youtube.com/') # 等待页面加载完成(可根据网络情况调整时间) time.sleep(3) # 用XPATH定位第一个视频标题,选择器更精准稳定 title_element = driver.find_element(By.XPATH, '//ytd-rich-grid-media//h3//a') video_title = title_element.text driver.quit() return video_title @views.route('/') def home(): return render_template('home.html', text=scrapper())
方法二:验证静态HTML内容(快速排查)
如果不想用Selenium,可以先把请求到的静态HTML保存下来,确认里面是否包含你需要的内容:
def scrapper(): url = 'https://www.youtube.com/' web_response = requests.get(url).text # 保存响应到本地文件,打开查看实际内容 with open('youtube_static.html', 'w', encoding='utf-8') as f: f.write(web_response) soup = BeautifulSoup(web_response, 'lxml') # 先尝试获取静态里存在的内容,比如页面标题 return soup.title.text
如果打开youtube_static.html后发现没有视频卡片,说明必须用动态渲染的方式。
注意事项
- YouTube有反爬机制,频繁请求可能会被限制访问,建议添加请求头(模拟浏览器UA)和请求间隔。
- 爬取内容请遵守YouTube的服务条款,不要用于商业用途。
内容的提问来源于stack exchange,提问作者Klaus
相关产品推荐
相关产品推荐

