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

Selenium Python点击框选项无法保留的技术求助

问题:Selenium操作xcweather无法保留自定义数据列设置

我编写了用于自动化收集天气报告的Python脚本,基于Selenium操作xcweather网站。该网站支持通过“添加列”下拉框的复选框选择额外数据列,手动操作时选择会被保存,但脚本中无论是先手动设置选择后保存/加载Cookie,还是直接用Selenium点击复选框,都无法保留所选列,脚本运行后仅显示基础天气数据列。

相关代码:

# -*- coding: utf-8 -*-
"""
Windows 10 Desktop
Python 3.8
AUTOMATE COLLECTION OF IRISH WEATHER FORECASTS
https://www.xcweather.co.uk/forecast/gl50_4sh
"""


import time
# import os

# from PIL import Image

from selenium import webdriver
# from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


from selenium.webdriver.firefox.options import Options
options = Options()
options.binary_location = r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe" 
driver = webdriver.Firefox(options=options, executable_path = "C:\Windows\geckodriver.exe")


driver.implicitly_wait(10)

driver.get("https://www.xcweather.co.uk/forecast/")

# save cookie preferences and exit acceptance button - click

wait = WebDriverWait(driver, 40) # explicit wait set 

element = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'css-1uf3ch9')))
element.click()
print("\n\nThe First Window Opened: ", driver.title,"\n")

# select additional 9 data columns
# NOT WORK !!
# first reset


#element = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'reset')))

#element = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[2]/table/tbody  /tr[2]\/td[3]/span[3]/div/div/form/table/tbody/tr[10]/td/a')))
#driver.execute_script("arguments[0].click();", element)
#element.click()
print("\n\nData Columns Reset: \n")

#element = wait.until(EC.element_to_be_clickable((By.NAME, 'atemp')))
#element = driver.find_element(('name', 'atemp'))
#element.click()
print("\n\nApparent Data Column Reset: \n")


placenames = ["Dublin", "Cork", "Limerick"]

driver.maximize_window()

for el in range(len(placenames)):
    
    time.sleep(3)
    # element = WebDriverWait(driver, 10).until(
    # EC.presence_of_element_located((By.ID, "myDynamicElement"))
    #input = driver.find_element(By.ID, "location-search-input")
   
    
    input = wait.until(EC.presence_of_element_located((By.ID, "loc_input")) ) 
    time.sleep(3)
    input.clear()
    time.sleep(3)
    input.send_keys(placenames[el])
    time.sleep(3)
    print("\nPLACE NAME ENTERED")
   
    button2 = wait.until(EC.element_to_be_clickable((By.ID, "searchbutton")))
    button2.click()
    time.sleep(3)
    
    print("\nThe Current Window Opened: ", driver.title,"\n")
    
    folder = "C:\\Users\\Robert\\Desktop"
    mypath = folder + "\\" + placenames[el] + "_XC" +'.png'
    
    # see https://reflect.run/articles/how-to-take-screenshot-inside-selenium-webdriver/
    
    # lambda function to find the value of X. We get the value by executing 
    # DOM JavaScript functions. The second line is to resize the window.
    S = lambda X: driver.execute_script('return document.body.parentNode.scroll'+X)
    # https://javascript.info/size-and-scroll-window
    print("\nS value: ",S)  
    
    driver.set_window_size(S('Width'),S('Height')) # May need manual adjustment                                                                                                                
    time.sleep(3)
    driver.find_element_by_tag_name('body').screenshot(mypath)
    time.sleep(3)
    driver.save_screenshot(mypath)
    print("\nSCREENSHOT TAKEN")
    print("\nSCREENSHOT SAVED: ", mypath)
    
    time.sleep(3)
    
"""
CODE USED TO SAVE AND LOAD COOKIES
time.sleep(60)

driver.delete_all_cookies() # clean up
if os.path.exists('cookies.pkl'):
    cookies = pickle.load(open("cookies.pkl", "rb"))
    for cookie in cookies:
        driver.add_cookie(cookie) # reaad in cookies to browser
    driver.refresh()
    time.sleep(5)
pickle.dump(driver.get_cookies(), open("cookies.pkl", "wb")) 
# save cookies to file

# You should add the above code just below the login code. 
# pickle.dump(driver.get_cookies(), open("cookies.pkl", "wb"))
# view pickle file in Word with utf8 encoding selected

"""
    
   
driver.quit()

解决方案

1. 改用localStorage保存偏好设置

xcweather大概率用localStorage而非Cookie存储列展示偏好,之前的Cookie保存逻辑无效。可以通过以下步骤实现:

  • 手动打开网站设置好需要的列,在浏览器控制台执行localStorage查看对应键值(比如columns)
  • 脚本中添加localStorage的保存与加载逻辑

示例代码:

import pickle

# 保存localStorage数据
def save_local_storage(driver, filename):
    local_storage = driver.execute_script("return window.localStorage;")
    with open(filename, 'wb') as f:
        pickle.dump(local_storage, f)

# 加载localStorage数据
def load_local_storage(driver, filename):
    with open(filename, 'rb') as f:
        local_storage = pickle.load(f)
    for key, value in local_storage.items():
        driver.execute_script(f"window.localStorage.setItem('{key}', '{value}');")
    driver.refresh()

# 首次运行时手动设置列后执行保存
# save_local_storage(driver, 'xcweather_localstorage.pkl')

# 后续运行时加载
load_local_storage(driver, 'xcweather_localstorage.pkl')

2. 修复复选框操作逻辑

之前的定位代码未正确执行,需要先展开「添加列」下拉框,再定位并点击复选框,确保触发保存:

# 点击展开"添加列"下拉框(需根据页面实际元素调整定位)
add_columns_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), '添加列')]")))
add_columns_btn.click()

# 选择体感温度列(name='atemp')
atemp_checkbox = wait.until(EC.element_to_be_clickable((By.NAME, 'atemp')))
if not atemp_checkbox.is_selected():
    atemp_checkbox.click()

# 点击保存按钮(如果存在)
save_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '保存')]")))
save_btn.click()

# 关闭下拉框
add_columns_btn.click()

3. 页面跳转后重新加载设置

每次搜索新城市页面会刷新,需在页面加载完成后重新执行列设置或加载localStorage,可将逻辑封装为函数,在循环中调用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:25:51