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

GCP Windows虚拟机上Selenium提取网站价格失败及属性错误求助

问题描述

本地运行代码可正常从Hepsiburada网站提取商品价格,但在Google Cloud Platform(GCP)的Windows Server 2022 Datacenter虚拟机上运行时,无法获取价格信息且抛出错误:AttributeError: 'WebElement' object has no attribute 'find_element_by_xpath'。

运行代码

from bs4 import BeautifulSoup
import undetected_chromedriver as uc
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

options = uc.ChromeOptions()
options.add_argument('--blink-settings=imagesEnabled=false') # 禁用图片加速页面加载
options.add_argument('--disable-notifications')
prefs = {"profile.default_content_setting_values.notifications" : 2}
options.add_experimental_option("prefs",prefs)
driver = uc.Chrome(options=options)

driver.get('https://www.hepsiburada.com/pinar-tam-yagli-sut-4x1-lt-pm-zypinar153100004')

try:
    price_element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'offering-price')))
    price = float(price_element.find_element_by_xpath('./span[1]').text + '.' + price_element.find_element_by_xpath('./span[2]').text)
except:
    print("there is no price info...")

已尝试的ChromeOptions参数

options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--disable-extensions')
options.add_argument('--disable-notifications')
options.add_argument('--disable-popup-blocking')

本地与虚拟机均安装Google Chrome 111.0.5563.65(64位),虚拟机使用Jupyterlab 3.4.4,已关闭防火墙。


问题原因

  1. Selenium版本不兼容:本地和虚拟机的Selenium版本可能不一致。Selenium 4.x已移除find_element_by_xpath这类旧API,统一使用find_element(By.XPATH, 路径)格式。如果虚拟机安装的是Selenium 4.x,直接调用旧方法就会触发该错误。
  2. 页面渲染/反爬差异:虚拟机环境下Chrome大概率以无头模式运行,页面渲染逻辑、JS执行环境和本地可视化模式有区别;同时Hepsiburada可能识别到服务器IP、系统指纹等特征,返回了和本地不同的页面结构,导致price_element并非预期的DOM元素,或子span标签不存在。
  3. 依赖库版本不匹配:undetected-chromedriver版本和Chrome版本不兼容,导致元素定位逻辑异常。

修复方案

  1. 统一Selenium元素查找语法:替换旧API为Selenium 4.x兼容写法:
    # 修改价格提取代码
    price = float(price_element.find_element(By.XPATH, './span[1]').text + '.' + price_element.find_element(By.XPATH, './span[2]').text)
    
  2. 优化无头模式配置:明确指定无头模式,添加反检测参数模拟正常浏览器环境:
    options.add_argument('--headless=new')  # Selenium 4.x推荐的无头模式
    options.add_argument('--window-size=1920,1080')  # 设置窗口尺寸避免布局异常
    options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36')  # 模拟正常UA
    
  3. 增强等待与错误排查:延长等待时间,添加子元素等待逻辑,同时捕获具体异常并保存页面源码排查:
    try:
        price_element = WebDriverWait(driver, 15).until(EC.visibility_of_element_located((By.ID, 'offering-price')))
        # 等待子span元素加载完成
        span1 = WebDriverWait(price_element, 10).until(EC.visibility_of_element_located((By.XPATH, './span[1]')))
        span2 = WebDriverWait(price_element, 10).until(EC.visibility_of_element_located((By.XPATH, './span[2]')))
        price = float(span1.text + '.' + span2.text)
        print(f"提取价格:{price}")
    except AttributeError as e:
        print(f"元素调用错误:{e}")
        print(f当前price_element类型:{type(price_element)}")
        # 保存页面源码到本地排查结构差异
        with open('page_source.html', 'w', encoding='utf-8') as f:
            f.write(driver.page_source)
    except Exception as e:
        print(f"其他错误:{e}")
    
  4. 匹配依赖版本:确保虚拟机上的undetected-chromedriver版本与Chrome 111.0.5563.65完全兼容,可通过pip install undetected-chromedriver==对应版本指定安装。

本地与虚拟机环境差异

  1. 依赖库版本:本地和虚拟机的Selenium、undetected-chromedriver版本可能不同,导致API支持差异。
  2. 浏览器运行模式:本地是可视化界面运行Chrome,虚拟机默认无头模式,页面渲染、JS执行环境存在区别。
  3. 系统特征:虚拟机的服务器IP、Windows Server系统指纹与本地个人电脑不同,容易触发网站反爬机制。
  4. 资源限制:虚拟机的CPU、内存资源可能少于本地,导致页面加载不完全、元素渲染延迟。

内容的提问来源于stack exchange,提问作者user14178341

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 23:27:51