使用requests.get()保存YouTube播放列表页面失效求助
解决YouTube搜索页面保存后仅显示头部的问题
这个问题我之前也碰到过,核心原因是YouTube的搜索结果是通过JavaScript动态渲染生成的——你用requests.get()拿到的只是最基础的HTML框架,里面的视频列表内容是浏览器加载页面后执行JS才会填充进去的,直接保存这个静态HTML自然看不到内容。下面给你几个可行的解决思路:
方法1:用Selenium模拟浏览器渲染(最直观的解决方案)
Selenium会启动真实的浏览器,等待页面完全加载(包括JS执行后的内容),这样就能拿到完整的渲染后页面。
步骤:
- 安装Selenium:
pip install selenium - 下载对应浏览器的驱动(比如ChromeDriver,要和你的Chrome版本匹配)
- 修改代码如下:
import pandas as pd import numpy as np import re import time import bs4 as bs4 import json from selenium import webdriver from selenium.webdriver.chrome.options import Options queries = ["machine+learning", "data+science", "kaggle"] url = "https://www.youtube.com/results?search_query={query}&sp=CAI%253D&p={page}" # 配置Chrome选项,可选无头模式(不显示浏览器窗口) chrome_options = Options() chrome_options.add_argument("--headless=new") chrome_options.add_argument("--disable-gpu") driver = webdriver.Chrome(options=chrome_options) try: for query in queries: for page in range(1,21): urll = url.format(query=query, page=page) print(urll) driver.get(urll) # 等待页面加载完成,这里可以根据实际情况调整等待时间 time.sleep(3) # 获取完整渲染后的页面源码 page_source = driver.page_source with open("./dados_brutos/{}_{}.html".format(query,page), 'w+', encoding='utf-8') as output: output.write(page_source) time.sleep(2) finally: driver.quit()
这样保存的HTML打开后就能看到完整的搜索结果了。
方法2:使用YouTube Data API(官方推荐,更稳定)
如果你的需求是获取播放列表/视频数据,而不是保存HTML页面,用官方API是更好的选择——避免反爬限制,还能直接拿到结构化的JSON数据,不用解析HTML。
大致步骤:
- 去Google Cloud控制台创建项目,启用YouTube Data API v3,获取API密钥
- 安装google-api-python-client:
pip install google-api-python-client - 示例代码(搜索播放列表):
from googleapiclient.discovery import build import json import time API_KEY = "你的API密钥" queries = ["machine learning", "data science", "kaggle"] youtube = build('youtube', 'v3', developerKey=API_KEY) for query in queries: next_page_token = None for page in range(1,21): request = youtube.search().list( q=query, part='snippet', type='playlist', # 指定搜索播放列表 pageToken=next_page_token, maxResults=50 # 每页最多50条结果 ) response = request.execute() # 保存结构化数据 with open("./dados_brutos/{}_{}.json".format(query.replace(" ","+"),page), 'w+') as output: json.dump(response, output, indent=2) next_page_token = response.get('nextPageToken') if not next_page_token: break # 没有更多页面就停止 time.sleep(1)
这个方法的好处是数据更可靠,不会因为YouTube页面结构变化而失效。
补充:静态请求的优化(效果有限)
如果你坚持想用requests,可以先尝试添加浏览器请求头模拟真实访问,但大概率还是解决不了动态加载的问题,不过可以试试:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } response = rq.get(urll, headers=headers)
但还是那句话,YouTube的核心内容是JS动态加载的,这个方法只能解决部分反爬拦截,拿不到完整内容。
内容的提问来源于stack exchange,提问作者Rôger Andrade
相关产品推荐
相关产品推荐

