如何用Python+Selenium爬取YouTube评论、回复及互动数据?
解决YouTube评论及回复爬取的Selenium方案
先说说你之前代码的核心问题:
- 没触发回复展开:YouTube的评论回复默认是折叠状态,必须点击
View X replies按钮才会加载实际内容,你之前的代码只定位了回复区域,但没触发点击操作,所以只能拿到按钮文本,拿不到真实回复内容。 - 定位逻辑不全:只抓取了主评论的文本内容,完全缺失了点赞数、点踩数、发布日期这些关键字段的定位逻辑。
- 滚动加载不够精准:单纯按
END键全局滚动可能会漏掉部分评论加载,最好直接针对评论区容器滚动,避免无效操作。
修正后的完整代码
下面是能爬取主评论、评论回复、点赞数、发布日期的完整代码,我加上了详细注释:
import time import csv 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 from selenium.common.exceptions import ElementNotInteractableException, StaleElementReferenceException def scrape_youtube_comments(url, chrome_driver_path): # 初始化浏览器 driver = webdriver.Chrome(executable_path=chrome_driver_path) driver.get(url) wait = WebDriverWait(driver, 10) # 获取视频标题 title = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="container"]/h1/yt-formatted-string'))).text print(f"正在爬取视频:{title}") # 滚动到评论区位置 driver.execute_script("window.scrollTo(0, document.getElementById('comments').offsetTop);") time.sleep(3) # 滚动加载所有主评论 last_height = driver.execute_script("return document.getElementById('comments').scrollHeight") while True: # 滚动评论区到底部 driver.execute_script("document.getElementById('comments').scrollTo(0, document.getElementById('comments').scrollHeight);") time.sleep(2) # 检查是否加载完成(高度不再变化) new_height = driver.execute_script("return document.getElementById('comments').scrollHeight") if new_height == last_height: break last_height = new_height # 点击所有"View X replies"按钮,展开回复内容 reply_buttons = wait.until(EC.presence_of_all_elements_located((By.XPATH, '//paper-button[@id="more" and @aria-label]'))) for button in reply_buttons: try: # 滚动到按钮可见位置,避免点击失败 driver.execute_script("arguments[0].scrollIntoView();", button) time.sleep(1) button.click() time.sleep(2) except (ElementNotInteractableException, StaleElementReferenceException): # 跳过已经展开或无法点击的按钮 continue # 准备存储所有评论数据 all_comments_data = [] # 遍历所有主评论块 comment_blocks = wait.until(EC.presence_of_all_elements_located((By.XPATH, '//ytd-comment-thread-renderer'))) for block in comment_blocks: try: # 抓取主评论核心信息 main_comment_text = block.find_element(By.XPATH, './/yt-formatted-string[@id="content-text"]').text like_count = block.find_element(By.XPATH, './/span[@id="vote-count-middle"]').text publish_date = block.find_element(By.XPATH, './/a[@id="author-text"]/following-sibling::yt-formatted-string').text # YouTube现在默认隐藏点踩数,这里做特殊标注 dislike_count = "无法直接获取(YouTube已隐藏)" # 添加主评论数据到列表 all_comments_data.append({ "类型": "主评论", "内容": main_comment_text, "点赞数": like_count, "点踩数": dislike_count, "发布日期": publish_date }) # 抓取当前主评论下的所有回复 replies = block.find_elements(By.XPATH, './/ytd-comment-replies-renderer//yt-formatted-string[@id="content-text"]') reply_dates = block.find_elements(By.XPATH, './/ytd-comment-replies-renderer//a[@id="author-text"]/following-sibling::yt-formatted-string') reply_likes = block.find_elements(By.XPATH, './/ytd-comment-replies-renderer//span[@id="vote-count-middle"]') for idx, reply in enumerate(replies): reply_text = reply.text reply_date = reply_dates[idx].text if idx < len(reply_dates) else "未知" reply_like = reply_likes[idx].text if idx < len(reply_likes) else "0" all_comments_data.append({ "类型": "回复", "内容": reply_text, "点赞数": reply_like, "点踩数": dislike_count, "发布日期": reply_date }) except Exception as e: print(f"处理评论块时出错:{e}") continue # 将数据写入CSV文件 with open("youtube_comments_full.csv", "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=["类型", "内容", "点赞数", "点踩数", "发布日期"]) writer.writeheader() writer.writerows(all_comments_data) print(f"爬取完成,共获取{len(all_comments_data)}条评论/回复,已保存到youtube_comments_full.csv") driver.quit() # 调用函数,替换成你的ChromeDriver路径和目标视频URL if __name__ == "__main__": CHROME_PATH = "/Users/Downloads/chromedriver" VIDEO_URL = "https://www.youtube.com/watch?v=qBp1rCz_yQU" scrape_youtube_comments(VIDEO_URL, CHROME_PATH)
关键步骤说明:
- 精准滚动评论区:直接定位评论区DOM元素
comments进行滚动,比全局滚动更高效,避免干扰页面其他元素。 - 自动展开回复:遍历所有回复展开按钮,处理可能的元素交互异常(比如按钮已经被点击过)。
- 完整字段抓取:针对主评论和回复分别定位内容、点赞、日期字段,适配YouTube当前的页面结构。
- 异常处理:添加了常见的Selenium异常捕获,避免单个评论出错导致整个程序崩溃。
注意事项:
- 确保你的ChromeDriver版本和Chrome浏览器版本一致,否则会出现兼容性问题。
- 可以根据网络情况调整
time.sleep的时长,避免因加载慢导致元素定位失败。 - YouTube有反爬机制,频繁爬取可能触发人机验证,建议适当增加延迟或使用代理。
内容的提问来源于stack exchange,提问作者sangeetha




