Selenium+Mudopy下载MP3后ChromeDriver卡在Hollywood bet页面求助
问题:ChromeDriver未正常退出,触发无关页面导致代码卡住
我用mudopy + Selenium实现了从YouTube抓取视频、转MP3并下载的功能,歌曲能成功下载,但ChromeDriver无法正常退出,反而自动打开了未请求的Hollywood bet页面并卡住,导致后续代码无法运行。
原始代码
def download(song, artist = None, play_after_downloading = True): """Downloads the video to given directory""" try: file=open("down_path.txt") down_path=file.read() down_path=down_path.strip() file.close() except: down_path = os.getcwd() print("It will not take more than 1 minute if your download speed is good") if artist: song=song+ ' by ' +artist video=song ''' chrome_options = webdriver.ChromeOptions() chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN") chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-dev-shm-usage") chrome_options.add_argument("--no-sandbox") driver = webdriver.Chrome(executable_path=os.environ.get("CHROMEDRIVER_PATH"), options=chrome_options) ''' chromeOptions=Options() chromeOptions.add_experimental_option("prefs",{"download.default_directory":down_path}) chromeOptions.add_argument("--headless") chromeOptions.add_argument('--ignore-certificate-errors-spki-list') chromeOptions.add_argument('--ignore-ssl-errors') #chromeOptions.add_argument("--disable-dev-shm-usage") #chromeOptions.add_argument("--no-sandbox") #chromeOptions.add_argument("--disable-javascript") #service = Service(executable_path=ChromeDriverManager().install()) #driver = webdriver.Chrome(service=service) #driver = webdriver.Chrome(executable_path=os.environ.get("CHROMEDRIVER_PATH"), options=chromeOptions) driver = webdriver.Chrome(ChromeDriverManager(path=os.getcwd()).install(),options=chromeOptions) wait=WebDriverWait(driver,3) presence = EC.presence_of_element_located visible = EC.visibility_of_element_located driver.get("https://www.youtube.com/results?search_query=" + str(video)) ads =True wait.until(visible((By.ID, "video-title"))) try: driver.find_element(By.XPATH,"//span[contains(@class,'style-scope ytd-badge-supported-renderer') and text()='Ad']") except Exception as e: ads=False if ads: vid = driver.find_element(By.ID,"video-title") vid.click() else: vid = driver.find_element(By.ID,"video-title") vid.click() #driver.find_element(By.ID,"video-title").click() print(driver.current_url) url=driver.current_url driver.get("https://ytmp3.cc/en13/") driver.maximize_window() driver.find_element(By.XPATH,"//*[@id='mp3']").click() driver.find_element(By.XPATH,"//*[@id='input']").send_keys(url) driver.find_element(By.XPATH,"//*[@id='submit']").click() time.sleep(6) driver.find_element(By.XPATH,"//*[@id='buttons' or @id='download']/span").click() #driver.find_element(By.XPATH,'//*[@id="download_list"]/div[1]').click() print("Downloading") time.sleep(10) driver.close() old_lst = os.listdir(down_path) while True: new_lst = os.listdir(down_path) if new_lst != old_lst: song = set(new_lst) - set(old_lst) song = str(song) song = song.replace("{","") song = song.replace("}","") song = song.strip("'") #song = song.replace(" ","") if Path(song).suffix == '.mp3': driver.quit() if play_after_downloading: print("Song downloaded to :"+down_path) #print("playing") #os.startfile(down_path+"/"+song) print(song) return song break #print(song) print("Hello from the creator of Mudopy,Smit Parmar and Ankit Raj Mahapatra.Do report bug if any") print("set download path") print("mudopy.download_path(r'download path') #dont forget to use 'r' while set download path") file.close()
问题根源
- 恶意跳转触发:ytmp3这类免费转换站点普遍植入广告,点击下载的操作可能误触隐藏的广告链接,导致打开无关页面。
- Driver关闭逻辑混乱:先调用
driver.close()关闭当前窗口,之后又在循环里调用driver.quit(),此时Driver实例已失效,未及时终止进程导致残留。 - 等待方式不可靠:依赖
time.sleep()固定等待时间,容易错过元素加载或提前触发操作,增加误触广告的概率。 - 元素定位不精准:下载按钮的XPATH范围太宽,可能定位到广告元素而非真正的下载按钮。
修复方案
1. 增强Chrome配置拦截跳转与广告
更新ChromeOptions,添加弹窗拦截、新页面阻止等参数:
chromeOptions=Options() chromeOptions.add_experimental_option("prefs",{"download.default_directory":down_path}) chromeOptions.add_argument("--headless=new") # 新版无头模式更稳定 chromeOptions.add_argument('--ignore-certificate-errors-spki-list') chromeOptions.add_argument('--ignore-ssl-errors') chromeOptions.add_argument("--disable-popup-blocking") # 拦截自动弹出窗口 chromeOptions.add_argument("--block-new-web-contents") # 阻止站点自动打开新页面 chromeOptions.add_experimental_option("excludeSwitches", ["enable-automation"]) # 避免被检测为自动化工具 chromeOptions.add_experimental_option('useAutomationExtension', False)
2. 修正Driver生命周期管理
用try-finally确保无论代码执行成功还是失败,都能关闭Driver:
driver = webdriver.Chrome(ChromeDriverManager(path=os.getcwd()).install(),options=chromeOptions) wait=WebDriverWait(driver, 10) try: # 所有业务逻辑放在try块内 driver.get("https://www.youtube.com/results?search_query=" + str(video)) # ... 中间代码省略 ... finally: driver.quit() # 无论如何都终止Driver进程
3. 替换time.sleep为显式等待
针对关键操作使用WebDriverWait,确保元素加载完成后再执行:
# 替换原有的time.sleep(6) wait.until(visible((By.XPATH, "//a[@id='download']"))) driver.find_element(By.XPATH, "//a[@id='download']").click() # 精准点击下载链接
4. 优化文件检测逻辑
简化循环检测逻辑,增加超时机制防止无限循环:
old_files = set(os.listdir(down_path)) timeout = time.time() + 60 # 设置60秒超时 while time.time() < timeout: new_files = set(os.listdir(down_path)) added_files = new_files - old_files for file in added_files: if Path(file).suffix == '.mp3': if play_after_downloading: print(f"Song downloaded to: {down_path}") print(file) return file time.sleep(1) # 每秒检测一次
修改后的完整代码
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.webdriver.chrome.options import Options from webdriver_manager.chrome import ChromeDriverManager import os from pathlib import Path import time def download(song, artist = None, play_after_downloading = True): """Downloads the video to given directory""" down_path = os.getcwd() try: with open("down_path.txt", "r") as file: down_path = file.read().strip() except: pass print("It will not take more than 1 minute if your download speed is good") video = f"{song} by {artist}" if artist else song # 配置Chrome选项 chromeOptions=Options() chromeOptions.add_experimental_option("prefs",{"download.default_directory":down_path}) chromeOptions.add_argument("--headless=new") chromeOptions.add_argument('--ignore-certificate-errors-spki-list') chromeOptions.add_argument('--ignore-ssl-errors') chromeOptions.add_argument("--disable-popup-blocking") chromeOptions.add_argument("--block-new-web-contents") chromeOptions.add_experimental_option("excludeSwitches", ["enable-automation"]) chromeOptions.add_experimental_option('useAutomationExtension', False) driver = webdriver.Chrome(ChromeDriverManager(path=os.getcwd()).install(), options=chromeOptions) wait=WebDriverWait(driver, 10) visible = EC.visibility_of_element_located try: # 搜索YouTube视频 driver.get(f"https://www.youtube.com/results?search_query={video}") wait.until(visible((By.ID, "video-title"))) # 广告检测 ads = True try: driver.find_element(By.XPATH,"//span[contains(@class,'style-scope ytd-badge-supported-renderer') and text()='Ad']") except: ads=False # 点击第一个视频 vid = driver.find_element(By.ID,"video-title") vid.click() print(driver.current_url) url=driver.current_url # 跳转转换站并操作 driver.get("https://ytmp3.cc/en13/") driver.find_element(By.XPATH,"//*[@id='mp3']").click() driver.find_element(By.XPATH,"//*[@id='input']").send_keys(url) driver.find_element(By.XPATH,"//*[@id='submit']").click() # 等待下载按钮并点击 wait.until(visible((By.XPATH, "//a[@id='download']"))) driver.find_element(By.XPATH, "//a[@id='download']").click() print("Downloading") # 检测MP3文件是否下载完成 old_files = set(os.listdir(down_path)) timeout = time.time() + 60 # 60秒超时 while time.time() < timeout: new_files = set(os.listdir(down_path)) added_files = new_files - old_files for file in added_files: if Path(file).suffix == '.mp3': if play_after_downloading: print(f"Song downloaded to: {down_path}") print(file) return file time.sleep(1) print("Download timed out") return None finally: # 确保Driver始终退出 driver.quit() print("Hello from the creator of Mudopy,Smit Parmar and Ankit Raj Mahapatra.Do report bug if any") print("set download path") print("mudopy.download_path(r'download path') #dont forget to use 'r' while set download path")
内容的提问来源于stack exchange,提问作者Nkosi Ncube
相关产品推荐
相关产品推荐

