Python+Selenium代码中sHoras变量未定义错误求助
问题分析与解决
核心问题定位
你的代码中sHoras相关的潜在问题主要有以下几点:
1. 低效且冗余的去重方式
用列表推导式执行sHoras.append()是不合理的,这种写法会生成一个由None组成的临时列表(因为append方法返回None),完全是内存浪费。正确的去重方式应该利用集合的特性:
# 保持原顺序的去重(推荐) sHoras = list(dict.fromkeys(horasT)) # 不关心顺序的话写法更简单 sHoras = list(set(horasT))
2. 索引越界风险
当indx(即24 - 当前小时数)大于sHoras的长度时,horas.append(sHoras[i])会直接抛出IndexError。必须先做长度校验:
# 简洁的切片写法,自动避免索引越界 horas = sHoras[:min(indx, len(sHoras))]
3. 无关数据混入horasT
你的horasT用//div/h3的XPATH获取所有h3标签,会把页面上非时间的h3内容也捞进来,导致sHoras包含无效数据。需要缩小XPATH范围,只定位小时相关的h3,比如根据页面实际结构调整:
# 示例(需根据页面真实元素类名调整) horasT = driver.find_elements(By.XPATH, "//div[contains(@class, 'DetailsSummary--hour--2FBp2')]/h3") # 同时过滤空字符串,避免无效数据 horasT = [h.text.strip() for h in horasT if h.text.strip()]
4. 类定义的错误使用
你定义了Clima类,但所有代码直接写在类内部,没有放在方法中,这会导致代码在类加载时就执行,不符合面向对象规范,也容易引发变量作用域问题。应该把代码放到类的方法里:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.service import Service import time import datetime class Clima(): def __init__(self): options = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-logging']) website = "https://weather.com/?Goto=Redirected" path = "C:/Users/Administrador/Downloads/chromedriver_win32/chromedriver.exe" self.driver = webdriver.Chrome(options=options, service=Service(path)) self.driver.get(website) def get_hourly_data(self): # 处理弹窗和语言设置 WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "truste-button3"))).click() time.sleep(3) WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'LanguageSelector--LanguageSelectorStatus--mXkYQ'))).click() WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div[3]/div[1]/header/div/div[2]/div[2]/nav/div/div/section/div/ul/li[2]'))).click() time.sleep(3) button = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.ID, 'LocationSearch_input'))) time.sleep(2) button.click() time.sleep(1) button.send_keys("Medellin, Antioquia") button.send_keys(Keys.RETURN) WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div[3]/div[3]/div/nav/div/div[1]/a[2]/span'))).click() time.sleep(2) # 获取温度(修复变量名重复问题) temp_elements = self.driver.find_elements(By.XPATH, "//summary/div/div/div/span[@class='DetailsSummary--tempValue--1K4ka']") temperatura = [elem.text for elem in temp_elements] # 获取小时(精准定位+去空) hora_elements = self.driver.find_elements(By.XPATH, "//div[contains(@class, 'DetailsSummary--hour--2FBp2')]/h3") horasT = [h.text.strip() for h in hora_elements if h.text.strip()] self.driver.quit() # 计算索引并处理小时列表 current_hour = int(datetime.datetime.now().strftime('%H')) indx = 24 - current_hour # 去重并保持顺序 sHoras = list(dict.fromkeys(horasT)) # 安全截取 horas = sHoras[:min(indx, len(sHoras))] return temperatura, horas # 实例化并调用 clima = Clima() temps, horas = clima.get_hourly_data() print(temps) print(horas)
5. 变量名重复问题
比如temperatura = [temperatura.text for temperatura in temperatura],循环变量和列表变量同名,虽然Python允许,但会降低代码可读性,容易引发逻辑混淆,建议改成不同的变量名(如上面代码中的temp_elements和temperatura)。
内容的提问来源于stack exchange,提问作者Juan Felipe Palacio Agudelo
相关产品推荐
相关产品推荐

