使用Selenium爬取Kayak航班数据时价格为None及字典重复问题求解
问题解决方案
你的两个问题分别由代码逻辑错误和属性调用错误导致,修复方案如下:
问题1:每次循环输出多个独立字典列表
问题原因
你把pprint.pprint(detail_flights[0:])这行打印代码放在了for循环内部,每往汇总列表里追加一条数据就会打印一次当前全量列表,自然会出现多次输出。
解决方法
把打印代码移动到for循环结束之后,等所有数据都追加到汇总列表后仅打印一次即可。
同时你的循环索引逻辑存在错误:你额外定义了变量j,在访问元素前先执行了j = j + 1,会导致跳过第一条航班数据,且最后会触发索引越界,建议直接遍历元素集合,无需额外定义索引变量。
问题2:price字段始终返回None
问题原因
你错误地把类名SrON-mb当成了元素的属性名调用get_attribute方法,SrON-mb是价格元素的类选择器,不是mainInfo元素自带的属性,自然返回None。
解决方法
在当前遍历到的mainInfo航班元素下,通过类选择器定位到价格子元素,再提取其文本内容即可。
修正后完整代码
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC import pprint # 提前配置chrome_options参数 chrome_options = webdriver.ChromeOptions() # 如有需要可以添加无头模式等配置 # chrome_options.add_argument('--headless') wd = webdriver.Chrome('chromedriver', chrome_options=chrome_options) wd.maximize_window() wd.implicitly_wait(50) wait = WebDriverWait(wd, 20) link = 'https://www.kayak.it/flights/MIL-BCN/2021-09-01/2021-09-02/?sort=bestflight_a' wd.get(link) # 处理 cookie 弹窗 try: wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='Accetta']"))).click() except: pass try: wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[id='onetrust-accept-btn-handler']"))).click() except: pass detail_flights = [] # 先提取固定的往返日期,不用放到循环里重复计算 date_path = link.replace('https://www.kayak.it/flights/', '') data_partenza = date_path[8:18] data_ritorno = date_path[19:29] # 获取所有航班主元素 elements = wd.find_elements(By.CSS_SELECTOR, ".mainInfo") if not elements: print('Nothing more to scrape') else: for elem in elements: try: # 滚动到当前元素可见 wd.execute_script("arguments[0].scrollIntoView(true);", elem) # 提取航班信息 flight_info = elem.get_attribute('innerText') # 提取价格:优先匹配已知类名,失效后可替换为页面最新的价格类选择器 price_elem = elem.find_element(By.CSS_SELECTOR, ".SrON-mb, .f8F1-price-text") price = price_elem.text.strip() # 追加到汇总列表 detail_flights.append({ 'flights': flight_info, 'price': price, 'data_partenza': data_partenza, 'data_ritorno': data_ritorno }) except Exception as e: # 打印异常方便排查,不需要可以注释 print(f"单条数据提取失败:{str(e)}") continue # 循环结束后统一打印汇总列表 pprint.pprint(detail_flights) # 关闭浏览器 wd.quit()
额外说明
如果后续遇到价格类名SrON-mb失效的情况,可以打开浏览器开发者工具,手动查看Kayak页面价格元素的最新类名替换即可。
内容的提问来源于stack exchange,提问作者Box
相关产品推荐
相关产品推荐

