在Koyeb运行Selenium Chrome时遇SessionNotCreatedException错误求助
问题描述
我有一个Python爬虫脚本,通过Selenium访问网站抓取数据,对比本地文本文件检测内容变更,有差异时向指定邮箱发送通知。脚本在Macbook Pro M3Pro(Silicon)本地运行正常,最初用Firefox开发,在Koyeb部署失败后换成Chrome,两种浏览器在本地均能正常运行,但在Koyeb上始终无法启动Chrome,报错如下:
Traceback (most recent call last): File "/workspace/main.py", line 84, in <module> latestNews=getLatestNews() ^^^^^^^^^^^^^^^ File "/workspace/main.py", line 55, in getLatestNews driver = webdriver.Chrome(options=chrome_options) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/.heroku/python/lib/python3.12/site-packages/selenium/webdriver/chrome/webdriver.py", line 45, in __init__ super().__init__( File "/app/.heroku/python/lib/python3.12/site-packages/selenium/webdriver/chromium/webdriver.py", line 66, in __init__ super().__init__(command_executor=executor, options=options) File "/app/.heroku/python/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py", line 212, in __init__ self.start_session(capabilities) File "/app/.heroku/python/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py", line 299, in start_session response = self.execute(Command.NEW_SESSION, caps)["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/.heroku/python/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py", line 354, in execute self.error_handler.check_response(response) File "/app/.heroku/python/lib/python3.12/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.SessionNotCreatedException: Message: session not created: Chrome failed to start: exited normally. (session not created: DevToolsActivePort file doesn't exist) (The process started from chrome location /app/.cache/selenium/chrome/linux64/127.0.6533.119/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) Stacktrace: #0 0x562e0a5f96ca <unknown> #1 0x562e0a2ca600 <unknown> #2 0x562e0a302485 <unknown> #3 0x562e0a2fe2f8 <unknown> #4 0x562e0a348ce8 <unknown> #5 0x562e0a33c643 <unknown> #6 0x562e0a30cd31 <unknown> #7 0x562e0a30d79e <unknown> #8 0x562e0a5c125b <unknown> #9 0x562e0a5c51f2 <unknown> #10 0x562e0a5ae615 <unknown> #11 0x562e0a5c5d82 <unknown> #12 0x562e0a59325f <unknown> #13 0x562e0a5e8e68 <unknown> #14 0x562e0a5e9040 <unknown> #15 0x562e0a5f849c <unknown> #16 0x7fdcb0bd5609 start_thread
我的代码文件
main.py
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support import expected_conditions from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.chrome.options import Options import os os.environ['MOZ_HEADLESS'] = '1' def send_email(subject, body, to_email): smtp_server = "smtp.zoho.eu" smtp_port = 587 from_email = "<mail>" password = "<password>" # Create the email msg = MIMEMultipart() msg['From'] = from_email msg['To'] = to_email msg['Subject'] = subject # Attach the email body msg.attach(MIMEText(body, 'plain')) try: # Set up the server server = smtplib.SMTP(smtp_server, smtp_port) server.starttls() # Upgrade the connection to a secure encrypted SSL/TLS connection server.login(from_email, password) # Send the email server.sendmail(from_email, to_email, msg.as_string()) print("Email sent successfully to: "+to_email+" !") except Exception as e: print(f"Failed to send email: {e}") finally: server.quit() # Close the connection to the server def getLatestNews(): # Start Selenium chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") driver = webdriver.Chrome(options=chrome_options) driver.implicitly_wait(6) driver.get("<LINK>") if((driver.find_element(By.XPATH, "//li[4]/a").text)=="Select Language TR\nTR"): driver.find_element(By.XPATH, "//li[4]/a").click() driver.find_element(By.XPATH, "//div[2]/div[8]/a").click() # Get the data from Web latestNews = (driver.find_element(By.XPATH, "//div[3]/div[2]/div/a").text) + " " + (driver.find_element(By.XPATH, "//span[2]").text)+ " " + (driver.find_element(By.XPATH, "//div[2]/div/span").text) + " " + (driver.find_element(By.XPATH, "//div[2]/span").text) print(latestNews) driver.close() return latestNews def is_changed(latestNews): f = open("latestNews.txt", "r") if(f.read()!=latestNews): f = open("latestNews.txt", "w") f.write(latestNews) f.close() return True f.close() return False def mailDelivery(latestNews): mailList= ["mail@gmail.com","example@gmail.com","test@gmail.com","test@gmail.com","othertest@gmail.com"] for i in mailList: send_email("Topic", "Some text\n\n"+latestNews, i) while(True): latestNews=getLatestNews() if (is_changed(latestNews)): mailDelivery(latestNews) else: print("No difference") time.sleep(3600)
requirements.txt
selenium
Procfile
web: python main.py
补充说明:使用Koyeb免费套餐,仅提供低性能CPU和512MB内存,已查阅大量StackOverflow方案但未解决,也未找到Koyeb上运行Selenium的相关案例。
解决方案
针对Koyeb的容器环境限制(尤其是内存)和Chrome启动失败的问题,按以下步骤修改:
1. 添加系统依赖文件
创建apt.txt文件,安装Chrome运行所需的系统库:
chromium-browser chromium-chromedriver libnss3-dev libgconf-2-4 libxss1 libappindicator1 libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator3-1 libnss3 lsb-release xdg-utils
2. 优化Chrome启动参数
修改getLatestNews()函数中的Chrome配置,适配低内存环境:
def getLatestNews(): # Start Selenium chrome_options = Options() # 新版无头模式,更稳定 chrome_options.add_argument("--headless=new") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") # 内存优化参数 chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--disable-extensions") chrome_options.add_argument("--disable-images") # 禁用图片节省内存 chrome_options.add_argument("--blink-settings=imagesEnabled=false") chrome_options.add_argument("--window-size=1920,1080") chrome_options.add_argument("--single-process") # 单进程减少内存占用 chrome_options.add_argument("--disable-application-cache") chrome_options.add_argument("--disable-background-networking") chrome_options.add_argument("--disable-default-apps") chrome_options.add_argument("--disable-translate") chrome_options.add_argument("--disable-popup-blocking") chrome_options.add_argument("--disable-logging") chrome_options.add_argument("--log-level=3") chrome_options.add_argument("--silent") # 指定系统安装的Chromium路径,避免版本兼容问题 chrome_options.binary_location = "/usr/bin/chromium-browser" driver = webdriver.Chrome(options=chrome_options) driver.implicitly_wait(3) # 缩短等待时间 driver.get("<LINK>") # ... 后续代码不变 # 替换driver.close()为driver.quit(),彻底释放资源 driver.quit() return latestNews
3. 修改Procfile为Worker进程
Koyeb默认将web进程当作HTTP服务检测端口,脚本是后台任务,无需端口监听,修改Procfile:
worker: python main.py
4. 优化文件读写逻辑
修复is_changed()函数的资源泄漏问题,处理文件不存在的情况:
def is_changed(latestNews): target_content = latestNews.strip() try: with open("latestNews.txt", "r") as f: current_content = f.read().strip() except FileNotFoundError: # 文件不存在则创建并写入 with open("latestNews.txt", "w") as f: f.write(target_content) return True if current_content != target_content: with open("latestNews.txt", "w") as f: f.write(target_content) return True return False
5. 升级requirements.txt,管理驱动版本
添加webdriver-manager自动匹配ChromeDriver版本:
selenium==4.15.0 webdriver-manager==4.0.1
修改driver初始化代码:
from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service # ... 在getLatestNews里 driver = webdriver.Chrome( service=Service(ChromeDriverManager().install()), options=chrome_options )
内容的提问来源于stack exchange,提问作者Tiwo
相关产品推荐
相关产品推荐

