You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3.12+Selenium爬虫Ubuntu卡顿,Windows正常问题求助

Selenium爬虫在Ubuntu 24.02服务器上实例化Chrome时挂起的问题

问题描述

我编写的房产网页抓取Selenium爬虫在Windows10上运行正常,但在Ubuntu24.02服务器上启动时直接挂起。两台设备均使用Python3.12.3版本,处于同一子网,Ubuntu可ping通目标网站、curl能获取内容,UFW已关闭,排除网络问题。

按下Ctrl+C终止进程后,栈信息显示卡在driver = webdriver.Chrome(service=service, options=chrome_options)的HTTP请求阶段:

bloom@bloom:~/centris_scrap/webScrap_Selenium$ python3 main.py -tp 1
^CTraceback (most recent call last):
  File "/home/bloom/centris_scrap/webScrap_Selenium/main.py", line 210, in <module>
    driver = webdriver.Chrome(service=service, options=chrome_options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/selenium/webdriver/chrome/webdriver.py", line 45, in __init__
    super().__init__(
  File "/usr/lib/python3/dist-packages/selenium/webdriver/chromium/webdriver.py", line 61, in __init__
    super().__init__(command_executor=executor, options=options)
  File "/usr/lib/python3/dist-packages/selenium/webdriver/remote/webdriver.py", line 208, in __init__
    self.start_session(capabilities)
  File "/usr/lib/python3/dist-packages/selenium/webdriver/remote/webdriver.py", line 292, in start_session
    response = self.execute(Command.NEW_SESSION, caps)["value"]
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/selenium/webdriver/remote/webdriver.py", line 345, in execute
    response = self.command_executor.execute(driver_command, params)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/selenium/webdriver/remote/remote_connection.py", line 302, in execute
    return self._request(command_info[0], url, body=data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/selenium/webdriver/remote/remote_connection.py", line 322, in _request
    response = self._conn.request(method, url, body=body, headers=headers)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/_request_methods.py", line 118, in request
    return self.request_encode_body(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/_request_methods.py", line 217, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/poolmanager.py", line 443, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 791, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 537, in _make_request
    response = conn.getresponse()
               ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 461, in getresponse
    httplib_response = super().getresponse()
                       ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/http/client.py", line 1428, in getresponse
    response.begin()
  File "/usr/lib/python3.12/http/client.py", line 331, in begin
    version, status, reason = self._read_status()
                              ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/http/client.py", line 292, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/socket.py", line 707, in readinto
    return self._sock.recv_into(b)
           ^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt

补充信息

编写简化版脚本,去掉所有抓取逻辑后,问题依然存在,还是卡在浏览器实例化阶段。简化后的脚本如下:

import logging

from selenium import webdriver
from selenium.common import ElementClickInterceptedException, NoSuchElementException
import argparse
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
import pandas as pd
from datetime import datetime
import uuid
import glob
import os
import os.path
from jinja2 import Environment, FileSystemLoader


def scrap_pages(driver):
    sqft=0
    year=0
    parking=0

    listings = driver.find_elements(By.CLASS_NAME, 'description')

    if listings[-1].text.split('\n')[0] == '': del listings[-1]

    for listing in listings:
        price=12333
        mls = '12333'
        prop_type = 'test'
        addr = 'test'
        city = 'test'
        sector = 'test'
        bedrooms = 1
        bathrooms=1
        listing_item = {
                'mls': mls,
                'price': price,
                'address': addr,
                'property type': prop_type,
                'city': city,
                'bedrooms': bedrooms,
                'bathrooms': bathrooms,
                'sector': sector,
                'living sqft': sqft,
                'lot sqft': sqft,
                'year': year,
                'parking': parking
            }
        centris_list.append(listing_item)


if __name__ == '__main__':
    today=datetime.now()
    today=today.strftime("%Y%m%d")
    start_time = time.time()
    UUID = str(uuid.uuid4())[-4:]

    parser = argparse.ArgumentParser()
    parser.add_argument("-s", "--skip_scrape", type=bool, default=False, help='dont scrape the webpage')
    parser.add_argument("-tp","--total_pages", type=int, help='number of pages to scrape')
    args = parser.parse_args()

    filename = f"centris_{today}_{UUID}_app.log"

    logging.basicConfig(
        filename=filename,
        level=logging.INFO,
        datefmt="%Y-%m-%d %H:%M",
        force=True
    )

    logging.info(f"We are starting the app")
    logging.info(f"We are scraping : {args.total_pages}")

    if not args.skip_scrape:
        chrome_options = Options()
        chrome_options.add_experimental_option("detach", True)
        chrome_options.add_argument('--headless')
        user_agent_win = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.6943.53 Safari/537.36'
        user_agent_u24 = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.6943.53 Safari/537.36'

        driver_path_win = 'C:\\WebDriver\\bin\\chromedriver132\\chromedriver.exe'
        driver_path_u24 = r'/usr/lib/chromium-browser/chromedriver'

        user_agent = user_agent_win if os.path.exists(driver_path_win) else user_agent_u24
        chrome_options.add_argument(f'user-agent={user_agent}')

        service = ChromeService(executable_path=driver_path_win) if os.path.exists(driver_path_win) else ChromeService(executable_path=driver_path_u24)
        driver = webdriver.Chrome(service=service, options=chrome_options)

        centris_list = []
        url = 'https://www.centris.ca/en/properties~for-sale~brossard?view=Thumbnail'
        '''
        driver.get(url)
        time.sleep(5)
        driver.find_element(By.ID, 'didomi-notice-agree-button').click()
        total_pages = driver.find_element(By.CLASS_NAME, 'pager-current').text.split('/')[1].strip()
        total = args.total_pages if args.total_pages is not None else int(total_pages)
        for i in range(0, total):
            try:
                scrap_pages(driver)
                driver.find_element(By.CSS_SELECTOR, 'li.next> a').click()
                time.sleep(3)
            except ElementClickInterceptedException as initial_error:
                try:
                    if len(driver.find_elements(By.XPATH, ".//div[@class='DialogInsightLightBoxCloseButton']")) > 0:
                        driver.find_element(By.XPATH, ".//div[@class='DialogInsightLightBoxCloseButton']").click()
                        time.sleep(3)
                    print('pop-up closed')
                    scrap_pages(driver)
                    driver.find_element(By.CSS_SELECTOR, 'li.next> a').click()
                    time.sleep(3)
                except NoSuchElementException:
                    raise initial_error
        '''
        driver.close()

    end_time=time.time()
    elapsed_seconds =end_time-start_time
    elapsed_time=elapsed_seconds/60
    logging.info(f"excution time is {elapsed_time:.2f}")

解决方案

  • 移除detach选项:detach=True会让浏览器在驱动退出后保持运行,无头服务器环境下容易引发进程阻塞,删除chrome_options.add_experimental_option("detach", True)。
  • 完善无头模式参数:Ubuntu无GUI环境下,仅--headless不够,添加以下适配参数:
    chrome_options.add_argument('--headless=new')  # 新版无头模式,兼容性更强
    chrome_options.add_argument('--no-sandbox')    # 禁用沙箱,避免权限限制
    chrome_options.add_argument('--disable-dev-shm-usage')  # 解决/dev/shm空间不足问题
    chrome_options.add_argument('--disable-gpu')   # 无头模式无需GPU加速
    
  • 校验ChromeDriver与浏览器版本匹配:执行chromium-browser --version和chromedriver --version确认版本完全一致,版本不匹配会导致启动失败或阻塞。
  • 指定Chrome二进制路径:手动指定浏览器二进制文件位置,避免Selenium找不到执行文件:
    chrome_options.binary_location = '/usr/bin/chromium-browser'  # 根据实际路径调整
    
  • 添加驱动启动超时:设置服务启动超时,防止无限挂起:
    service = ChromeService(executable_path=driver_path_u24)
    service.start_timeout = 10  # 设置10秒超时阈值
    

内容的提问来源于stack exchange,提问作者D.Zou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:12:02