如何在Ubuntu VDS服务器上运行Selenium Python程序?
Selenium Chrome在Ubuntu 22 VDS启动失败:DevToolsActivePort文件不存在
我开发了一款基于Selenium的Python程序,用于向指定频道发布hentai内容。该程序在Windows环境下可正常运行,但部署至Ubuntu 22版本的VDS服务器时出现问题。已安装Selenium兼容的Chrome 114.0.5735.90版本,运行程序时抛出WebDriverException错误,提示Chrome启动异常、DevToolsActivePort文件不存在。
程序代码
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from random import choice, randint import logging from aiogram import Bot, Dispatcher, types from aiogram.contrib.fsm_storage.memory import MemoryStorage import requests from os import remove, getcwd from config import url TOKEN = "6208140357:AAEB94wTzQGqIITJMyv-GbvWA3OMyZ59Bzg" logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) bot = Bot(token=TOKEN) storage = MemoryStorage() dp = Dispatcher(bot, storage=storage) all_href = [] photos_links = [] src_link = [] group_urls = [] rn = randint(1, 3) if rn == 1: tags = ['amber_%28genshin_impact%29+#', 'lisa_%28genshin_impact%29+', 'barbara_%28genshin_impact%29+', 'noelle_%28genshin_impact%29+', 'fischl+', 'sucrose_%28genshin_impact%29+', '%09Beidou', 'Candace', 'collei+', 'dehya+', 'eula_%28genshin_impact%29+', 'eula+', 'faruzan+', 'ganyu+', 'hu_tao+', 'jean_%28genshin_impact%29+', 'kamisato_ayaka_%28genshin_impact%29+', 'keqing_%28genshin_impact%29+', 'kirara_%28genshin_impact%29+', 'kujou_sara+', 'kuki_shinobu+', 'layla_%28genshin_impact%29+', 'mona_megistus+', 'nilou+', 'ningguang+', 'raiden_shogun+', 'rosaria_%28genshin_impact%29+', 'sangonomiya_kokomi+', 'shenhe_%28genshin_impact%29+', 'xiangling+', 'yae_miko_%28genshin_impact%29+', 'yanfei+', 'yelan+', 'yoimiya+'] elif rn == 2: tags = ['asta_%28honkai%3A_star_rail%29+', 'fu_xuan', 'herta', 'himeko+', 'kafka_%28honkai%3A_star_rail%29+', 'march_7th+', 'natasha_%28honkai%3A_star_rail%29+', 'pela', 'qingque_%28honkai%3A_star_rail%29+', 'seele_%28honkai%3A_star_rail%29+', 'serval', 'silver_wolf_%28honkai%3A_star_rail%29+', 'tingyun'] elif rn == 3: tags = ['azur_lane', 'no_bra', 'nipples', 'open_shirt', 'pantsu', 'skirt_lift', 'dress', 'animal_ears', 'bunny_ears', 'ass', 'bikini', 'see_through', 'seifuku', 'nopan', 'feet', 'cleavage', 'wet'] ''' tags = ['amber_%28genshin_impact%29+#', 'lisa_%28genshin_impact%29+', 'barbara_%28genshin_impact%29+', 'noelle_%28genshin_impact%29+', 'fischl+', 'sucrose_%28genshin_impact%29+', '%09Beidou', 'Candace', 'collei+', 'dehya+', 'eula_%28genshin_impact%29+', 'eula+', 'faruzan+', 'ganyu+', 'hu_tao+', 'jean_%28genshin_impact%29+', 'kamisato_ayaka_%28genshin_impact%29+', 'keqing_%28genshin_impact%29+', 'kirara_%28genshin_impact%29+', 'kujou_sara+', 'kuki_shinobu+', 'layla_%28genshin_impact%29+', 'mona_megistus+', 'nilou+', 'ningguang+', 'raiden_shogun+', 'rosaria_%28genshin_impact%29+', 'sangonomiya_kokomi+', 'shenhe_%28genshin_impact%29+', 'xiangling+', 'yae_miko_%28genshin_impact%29+', 'yanfei+', 'yelan+', 'yoimiya+', 'yun_jin+', 'kafka_%28honkai%3A_star_rail%29+', 'herta+', 'azur_lane', 'no_bra', 'nipples', 'open_shirt', 'pantsu', 'skirt_lift', 'dress', 'animal_ears', 'bunny_ears', 'ass', 'bikini', 'see_through', 'seifuku', 'nopan', 'feet', 'cleavage', 'wet', 'asta_%28honkai%3A_star_rail%29+', 'fu_xuan', 'herta', 'himeko+', 'kafka_%28honkai%3A_star_rail%29+', 'march_7th+', 'natasha_%28honkai%3A_star_rail%29+', 'pela', 'qingque_%28honkai%3A_star_rail%29+', 'seele_%28honkai%3A_star_rail%29+', 'serval', 'silver_wolf_%28honkai%3A_star_rail%29+', 'tingyun'] ''' t = None number = 0 number_2 = 0 chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--disable-extensions') webdriver_service = Service("root/kitsu-api/chromedriver_linux64/chromedriver") driver = webdriver.Chrome(service=webdriver_service, options=chrome_options) driver.get(f"{url}?page=1&tags={choice(tags)}") links = driver.find_elements(By.CSS_SELECTOR, 'a.thumb') for link in links: href = link.get_attribute('href') all_href.append(href) while number <= 5: if number_2 >= 15: number += 5 print("всі фото на цьому сайті вже були опубліковані...") with open("all_photos.txt", "a+", encoding='utf-8') as f: lines = f.readlines() link_3 = choice(all_href) t = None for i in lines: line = lines[i] if link_3 in line: t = True break if t == True: number_2 += 1 continue else: photos_links.append(link_3) f.write(f"{link_3}\n") number += 1 driver.quit() if number >= 5: for i in range(6): driver = webdriver.Chrome(service=webdriver_service, options=chrome_options) driver.get(photos_links[i]) links = driver.find_elements(By.CSS_SELECTOR, 'img.image') for link in links: image = link.get_attribute('src') src_link.append(image) driver.quit() @dp.message_handler(commands=['start']) async def start(message: types.Message): user_id = 2139742877 if int(user_id) != 2139742877: await message.reply("нажаль, цього бота може використовувати тільки його розробник. Пишіть сюди: @duxtaa") else: await message.reply("Bot is running") @dp.message_handler(commands=['chat_id']) async def chat_id_command(message: types.Message): chat_id = message.chat.id await message.answer(chat_id) @dp.message_handler(commands=['image']) async def send_photos(message: types.Message): user_id = 2139742877 if int(user_id) != 2139742877: await message.reply("нажаль, цього бота може використовувати тільки його розробник. Пишіть сюди: @duxtaa") else: for i in range(1, 6): url = src_link[i] response = requests.get(url) photo = response.content with open(f"photo_{i}.jpg", "wb") as file: file.write(photo) with open(f"photo_{i}.jpg", "rb") as file: await bot.send_document(-1001919858113, document=file, disable_notification=True) group_urls.append(url) message_id = message.message_id print(message_id) photo_ids = group_urls await bot.send_media_group(chat_id=-1001919858113, media=[types.InputMediaPhoto(media=photo_id) for photo_id in photo_ids]) await bot.send_message(chat_id=-1001919858113, text=f"{rn}") for i in range(1, 6): remove(f"photo_{i}.jpg") await bot.stop_polling() async def on_startup(dp): await bot.send_message(chat_id=-1001919858113, text="Bot is running") await send_photos(types.Message()) if __name__ == '__main__': from aiogram import executor executor.start_polling(dp, skip_updates=True, on_startup=on_startup)
错误栈
Traceback (most recent call last): File "/root/kitsu-api/send-anime-photos.py", line 7, in <module> driver=webdriver. Chrome (options=options) File "/usr/local/lib/python3.10/dist-packages/selenium/webdriver/chrome/webdriver.py", super (). __init__( File "/usr/local/lib/python3.10/dist-packages/selenium/webdriver/chromium/webdriver.py", super ().__init__( line 54, in _init_ File "/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/webdriver.py", line 206, in init File "/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/webdriver.py", line 291, in start_session response = self.execute (Command.NEW_SESSION, caps) ["value"] File "/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/webdriver.py", line 346, in execute "/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response File raise exception_class (message, screen, stacktrace) selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally. (unknown error: DevToolsActivePort file doesn't exist) (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) Stacktrace: self.start_session (capabilities) self.error_handler.check_response (response) #0 0x564f0ab2d4e3 <unknown> #1 0x564f0a85cc76 <unknown> #2 0x564f0a885d78 <unknown> #3 0x564f0a882029 <unknown> #4 0x564f0a8c0ccc <unknown> #5 0x564f0a8c047f <unknown> #6 0x564f0a8b7de3 <unknown> # 7 0x564f0a88d2dd <unknown> #8 0x564f0a88e34e <unknown> #9 0x564f0aaed3e4 <unknown> # 10 0x564f0aaf13d7 <unknown> #11 0x564f0aafbb20 <unknown> #12 0x564f0aaf2023 <unknown> #13 0x564f0aac01aa <unknown> #14 0x564f0ab166b8 <unknown> #15 0x564f0ab16847 <unknown>
解决方案
1. 补充Chrome无头模式必需参数
Linux无头环境下,Chrome需要额外参数避免端口和权限问题,修改你的ChromeOptions配置:
chrome_options = Options() chrome_options.add_argument('--headless=new') # 替代旧版--headless,兼容性更好 chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--disable-extensions') chrome_options.add_argument('--no-sandbox') # 禁用沙箱,Linux服务器必需 chrome_options.add_argument('--disable-dev-shm-usage') # 解决/dev/shm内存不足问题 chrome_options.add_argument('--remote-debugging-port=9222') # 指定固定调试端口,避免冲突
2. 修复ChromeDriver路径与权限
- 把ChromeDriver路径改为绝对路径:
"/root/kitsu-api/chromedriver_linux64/chromedriver",避免相对路径错误 - 给ChromeDriver添加可执行权限:
chmod +x /root/kitsu-api/chromedriver_linux64/chromedriver
3. 验证Chrome安装完整性
在服务器终端执行以下命令,确认Chrome能正常启动:
google-chrome --headless --no-sandbox --disable-gpu --dump-dom https://www.google.com
如果执行失败,重新安装对应版本的Chrome:
wget https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.90-1_amd64.deb dpkg -i google-chrome-stable_114.0.5735.90-1_amd64.deb apt-get install -f # 自动修复依赖缺失
4. 优化Chrome实例复用逻辑
代码中多次创建销毁Chrome实例易导致资源泄漏,建议复用单个实例:
with webdriver.Chrome(service=webdriver_service, options=chrome_options) as driver: # 初始页面获取链接 driver.get(f"{url}?page=1&tags={choice(tags)}") links = driver.find_elements(By.CSS_SELECTOR, 'a.thumb') for link in links: href = link.get_attribute('href') all_href.append(href) # 循环获取图片链接,复用同一个driver for photo_link in photos_links[:5]: driver.get(photo_link) img_links = driver.find_elements(By.CSS_SELECTOR, 'img.image') for img in img_links: src_link.append(img.get_attribute('src'))
内容的提问来源于stack exchange,提问作者Duxtaa
相关产品推荐
相关产品推荐

