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

Python+Selenium操作Kijiji Autos位置设置弹窗失败:无法输入邮编且无法选择禁用的半径下拉框

Python+Selenium操作Kijiji Autos位置设置弹窗失败:无法输入邮编且无法选择禁用的半径下拉框

老哥,我看了你的问题和代码,核心问题出在对「Set location」弹窗的理解上——它不是新的浏览器窗口,而是当前页面内的模态框(Modal),你之前的代码错误地去切换浏览器窗口了,这就导致后续操作全走偏了!我帮你梳理下问题和修正方案:

你的核心问题分析

  1. 错误切换浏览器窗口:手动点击「Set location」弹出的是页面内的浮动模态框,不是新的浏览器窗口,所以driver.switch_to.window()完全没必要,反而会让你在错误的上下文里操作元素(甚至可能操作到原页面隐藏的同名元素)。
  2. 邮编输入未触发验证:Kijiji的邮编输入框需要等待自动验证/补全完成,不是简单按回车就能触发的,直接按回车可能没触发网站的地址验证逻辑,导致半径下拉框一直处于禁用状态。
  3. 元素定位不够稳定:你用硬编码的XPATH定位「Set location」按钮,这类XPATH很容易因为页面结构变化失效,建议用网站提供的data-testid属性定位,更稳定。

修正后的代码示例

我把你的代码关键部分修正了,你可以替换对应片段试试:

# type: ignore

print('\nStarting program ...')

# Bring in basic libraries
import os
import time

# File names to be created
fnames = {
    'web':    'logging-web.txt',       # Webdriver console messages
}

# Check if the output files are in use - remove file if it exists and is not open
for fn in fnames:
    if os.path.isfile(fnames[fn]):
        try:
            os.remove(fnames[fn])
        except Exception as err:
            print(f"\nERROR: {err} - ABORTING ...",flush=True)
            exit(False)

# Bring in additional libraries
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Set up ChromeDriver options
chrome_options = Options()
chrome_options.add_argument('--remote-debugging-pipe')
chrome_options.add_argument('--incognito')
# 建议暂时关闭headless,方便你可视化看操作过程,调试没问题再打开
# chrome_options.add_argument('--headless=new')
chrome_options.add_argument('--accept-all-cookies')
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--ignore-ssl-errors')
chrome_options.add_argument('--disable-infobars')
chrome_options.add_argument('--disable-notifications')
chrome_options.add_argument('--log-level=3')

chrome_options.page_load_strategy = 'normal'

chrome_options.add_experimental_option('excludeSwitches',['enable-logging','enable-automation'])
chrome_options.add_experimental_option('prefs',{'profile.managed_default_content_settings.images':2})

# Set up ChromeDriver logging
wservice = webdriver.ChromeService(service_args=['--append-log','--readable-timestamp'],log_output=f"{fnames['web']}")
    
# Start the webdriver
driver = webdriver.Chrome(options=chrome_options,service=wservice)
driver.maximize_window()
driver.set_script_timeout(30)

url = 'https://www.kijijiautos.ca/cars/gmc/canyon/#ml=%3A&ms=9900%3B13&od=up&p=5000%3A&sb=p&yc=2024%3A2024'

print(f"\nGetting webpage {url} ...")
driver.get(url)
WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.TAG_NAME,'body')))

# 用data-testid定位Set location按钮,更稳定
set_location_btn = WebDriverWait(driver,30).until(
    EC.element_to_be_clickable((By.XPATH, '//button[@data-testid="LocationLabelLink"]'))
)
print(f"\nINFO: Set location button HTML={set_location_btn.get_attribute('outerHTML')}")
set_location_btn.click()

# 重点:不需要切换窗口!直接在当前页面定位模态框内的邮编输入框
# 等待模态框中的邮编输入框可见并可点击
postal_code_input = WebDriverWait(driver, 30).until(
    EC.element_to_be_clickable((By.ID, 'LocationAutosuggest'))
)
print(f"\nINFO: Postal code input before={postal_code_input.get_attribute('outerHTML')}")
# 清空输入框后输入邮编
postal_code_input.clear()
postal_code_input.send_keys('T1J 4C8')

# 关键步骤:等待邮编验证完成——直到半径下拉框从禁用变为可点击
# 这一步确保网站已经验证了你的邮编,启用了后续的半径选择
radius_dropdown = WebDriverWait(driver, 30).until(
    EC.element_to_be_clickable((By.ID, 'rd'))
)
print(f"\nINFO: Radius dropdown after verification={radius_dropdown.get_attribute('outerHTML')}")

# 选择1000公里半径
Select(radius_dropdown).select_by_value('1000')

# 勾选「Limit radius to province」复选框
province_checkbox = WebDriverWait(driver, 30).until(
    EC.element_to_be_clickable((By.NAME, 'limitedToProvince'))
)
print(f"\nINFO: Province checkbox={province_checkbox.get_attribute('outerHTML')}")
if not province_checkbox.is_selected():
    province_checkbox.click()

# 点击Apply按钮应用设置
apply_button = WebDriverWait(driver, 30).until(
    EC.element_to_be_clickable((By.LINK_TEXT, 'Apply'))
)
print(f"\nINFO: Apply button={apply_button.get_attribute('outerHTML')}")
apply_button.click()

# 等待页面更新:等待搜索结果区域刷新,这里用等待body元素失效(页面更新后body会重新渲染)
WebDriverWait(driver, 30).until(
    EC.staleness_of(driver.find_element(By.TAG_NAME, 'body'))
)
print("\nINFO: Page updated successfully!")

# 可以在这里继续处理更新后的页面数据
# ...

# End the driver
time.sleep(5)  # 留5秒让你看到更新后的页面,调试完成后可以去掉
driver.quit()

关键修正点说明

  1. 移除窗口切换逻辑:完全删掉原来的for winhan in driver.window_handles循环,因为模态框属于当前页面,不需要切换浏览器窗口。
  2. 等待邮编验证完成:用EC.element_to_be_clickable等待半径下拉框,确保网站已经验证了你的邮编,启用了后续的半径选择,这就解决了「禁用选项」的报错。
  3. 优化元素定位:用data-testid定位「Set location」按钮,避免页面结构变化导致XPATH失效。
  4. 暂时关闭headless:调试阶段建议关闭--headless=new,这样你可以看到Chrome浏览器的操作过程,更容易排查问题。

原执行日志报错(供参考)

Starting program ...

Getting webpage https://www.kijijiautos.ca/cars/gmc/canyon/#ml=%3A&ms=9900%3B13&od=up&p=5000%3A&sb=p&yc=2024%3A2024 ...

INFO: original window handle=5DCA8B95024DB03D50D0A6302BA77DE3

INFO: elem.before=<button class="hDZZVr bDZZVr b2MH0T f3yLIj" type="button" data-testid="LocationLabelLink">Set location</button>

INFO: elem.after=<button class="hDZZVr bDZZVr b2MH0T f3yLIj" type="button" data-testid="LocationLabelLink">Set location</button>

INFO: window handles=5DCA8B95024DB03D50D0A6302BA77DE3

ERROR: No new window created ...

INFO: elem2.before=<input aria-invalid="false" tabindex="0" autocomplete="off" id="LocationAutosuggest" placeholder="Type the location" type="text" value="" class="focus-visible" data-focus-visible-added="">

INFO: elem2.after=<input aria-invalid="false" tabindex="0" autocomplete="off" id="LocationAutosuggest" placeholder="Type the location" type="text" value="" class="focus-visible" data-focus-visible-added="">

INFO: elem3.before=<select id="rd" class="pnNiF7 cnNiF7" disabled="" name="rd" required="" tabindex="0" data-testid="LocationRadiusDropdown"><option value="5">+ 5 km</option><option value="10">+ 10 km</option><option value="15">+ 15 km</option><option value="25">+ 25 km</option><option value="50">+ 50 km</option><option value="100">+ 100 km</option><option value="150">+ 150 km</option><option value="250">+ 250 km</option><option value="500">+ 500 km</option><option value="750">+ 750 km</option><option value="1000">+ 1,000 km</option></select>
Traceback (most recent call last):
  File "C:\Users\david.DESKTOP-IH066BB\Documents\Software\CarSearch\testx.py", line 95, in <module>
    drop.select_by_value('1000')
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "C:\Users\david.DESKTOP-IH066BB\AppData\Local\Programs\Python\Python313\Lib\site-packages\selenium\webdriver\support\select.py", line 79, in select_by_value
    self._set_selected(opt)
    ~~~~~~~~~~~~~~~~~~^^^^^
  File "C:\Users\david.DESKTOP-IH066BB\AppData\Local\Programs\Python\Python313\Lib\site-packages\selenium\webdriver\support\select.py", line 213, in _set_selected
    raise NotImplementedError("You may not select a disabled option")

备注:内容来源于stack exchange,提问作者Wonkydave

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:48:02