Selenium爬取数据写入Pandas DataFrame仅存首值问题求助
问题根因
- DataFrame初始化位置错误:放在循环内部,每次遍历链接都会新建一个只包含当前单条数据的DataFrame,之前爬取的所有数据不会被保留
- 文件写入模式错误:使用
mode='w'覆盖写入,每次循环都会清空文件原有内容,仅写入当前单条数据,最终文件只会保留最后一次循环写入的内容 - Selenium接口写法过时:
find_element_by_xpath在新版本Selenium中已经被移除,运行会抛出属性错误 - 变量名不统一:WebDriverWait传入的驱动实例是
browser,后续操作使用的是driver,两个变量不一致会触发运行错误 - 细节错误:XPath表达式里
// span多余的空格会导致元素匹配失败;末尾的f.close()没有对应打开的文件句柄,属于无效代码
修复实现
首先在循环外部初始化空DataFrame用来累积所有爬取结果,循环内只做数据提取和追加,所有爬取完成后再统一做去重、写入操作:
import pandas as pd from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from random import randint from time import sleep import os # 循环外初始化空DataFrame,定义存储字段 df = pd.DataFrame(columns=['Product', 'Brand']) for link in links: try: sleep(randint(5,10)) driver.get(link) # 统一驱动变量名为driver,和后续操作保持一致 myElem = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CLASS_NAME, "item" ))) # 提取商品名称,单条值直接存字符串即可,不需要套列表 try: product = driver.find_element(By.CLASS_NAME, 'name').get_attribute('innerHTML') except Exception: product = "Other" # 提取品牌信息,替换已废弃的find_element_by_xpath写法,修正XPath多余空格 try: brand = driver.find_element(By.XPATH, "//span[contains(text(),'Brand')]/following-sibling::p").get_attribute('innerHTML') except Exception: brand = "Other" # 将当前爬取的单条数据追加到总DataFrame current_data = pd.DataFrame([[product, brand]], columns=['Product', 'Brand']) df = pd.concat([df, current_data], ignore_index=True) except Exception as e: # 打印异常信息方便排查失败链接,不要直接静默跳过 print(f"链接爬取失败: {link}, 错误信息: {str(e)}") continue # 所有爬取完成后再退出驱动 driver.quit()
两种存储逻辑实现
爬取完全部数据后,可根据需求选择写入模式:
- 追加新值自动去重
对累积的DataFrame先去重,再以追加模式写入文件,首次写入自动带表头,后续追加不再写入表头避免重复:# 按Product和Brand字段去重,保留第一条重复数据 df_dedup = df.drop_duplicates(subset=['Product', 'Brand'], keep='first') save_path = 'C:/product_data_append.tsv' # 判断文件是否存在,存在则追加且不写表头,不存在则新建并写表头 write_header = not os.path.exists(save_path) df_dedup.to_csv(save_path, sep='\t', mode='a', index=False, header=write_header) - 全量覆盖写入
每次运行都清空旧文件,写入本次爬取的全部去重后数据:df_dedup = df.drop_duplicates(subset=['Product', 'Brand'], keep='first') df_dedup.to_csv('C:/product_data_full.tsv', sep='\t', mode='w', index=False)
注意:文件路径不建议包含空格,避免部分环境下出现路径解析错误。
内容的提问来源于stack exchange,提问作者Artemy Panin
相关产品推荐
相关产品推荐

