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
相关产品推荐
相关产品推荐

