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

使用Pandas与Selenium处理邮编对应ISP数据时,Excel导出内容集中在一行的问题求助

解决Excel导出格式异常及数据显示问题

让我们一步步解决你遇到的两个核心问题:数据集中在同一行,以及存在\n和方括号的显示问题。

问题根源分析

  1. 单行显示问题:你创建DataFrame时,把整个address Series、pv1/pv2/pv3列表用[]包裹成了单个元素,比如{'Zip Code': [address]},这会让Pandas把整个列表当成一行的单元格值,而不是每个元素对应一行。
  2. 转义字符与方括号:因为单元格里存的是整个列表(而非单个字符串),所以Excel会显示方括号;而\n是网页文本里的换行符,直接保存会保留转义。
  3. 额外隐患:你每次循环都调用SeleniumSetup并退出浏览器,不仅效率极低,还可能导致部分查询因浏览器频繁启停失败。

修复方案与优化代码

下面是修改后的完整代码,我会标注关键修改点:

import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time

# 封装Selenium初始化逻辑,返回driver实例
def SeleniumSetup(url):
    driver = webdriver.Chrome()  # 根据你的实际浏览器调整驱动
    driver.get(url)
    return driver

def CheckXfinityList():
    # 读取Excel文件中的邮编数据
    df = pd.read_excel("BranchAddressList.xlsx")
    address_series = df["Zip Code"]
    # 初始化服务商列表,确保后续长度与邮编匹配
    pv1 = []
    pv2 = []
    pv3 = []

    # 优化:只初始化一次浏览器,循环结束后统一关闭
    driver = SeleniumSetup("https://www.highspeedinternet.com/providers")

    for zip_code in address_series:
        try:
            # 清空输入框,避免残留之前的邮编内容
            zip_input = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.ID, 'providerHero'))
            )
            zip_input.clear()
            zip_input.send_keys(str(zip_code))
            zip_input.send_keys(Keys.ENTER)
            
            # 用显式等待等待服务商列表加载完成,替代固定sleep
            WebDriverWait(driver, 15).until(
                EC.presence_of_element_located((By.XPATH, '//*[@id="residential"]/div[3]/div/div[1]'))
            )

            # 获取服务商名称并清理换行符
            provider1 = driver.find_element("xpath", '//*[@id="residential"]/div[3]/div/div[1]').text.replace('\n', ' ')
            provider2 = driver.find_element("xpath", '//*[@id="residential"]/div[4]/div[1]/div[1]').text.replace('\n', ' ')
            provider3 = driver.find_element("xpath", '//*[@id="residential"]/div[5]/div/div[1]').text.replace('\n', ' ')
            
            pv1.append(provider1)
            pv2.append(provider2)
            pv3.append(provider3)
        except Exception as e:
            print(f"邮编 {zip_code} 查询失败: {str(e)}")
            # 异常时添加空值,保证三个列表长度与邮编列表一致
            pv1.append(None)
            pv2.append(None)
            pv3.append(None)

    # 循环结束后关闭浏览器
    driver.quit()

    # 关键修复:直接使用原始Series和列表,不要用[]包裹
    top3 = pd.DataFrame({
        'Zip Code': address_series,
        'Internet Provider 1': pv1,
        'Internet Provider 2': pv2,
        'Internet Provider 3': pv3
    })

    # 导出Excel文件
    writer = pd.ExcelWriter('TopProviders.xlsx', engine='xlsxwriter')
    top3.to_excel(writer, sheet_name='Sheet1', index=False)
    writer.close()  # 用close替代save,适配现代Pandas版本

CheckXfinityList()

关键修改说明

  1. DataFrame创建逻辑:去掉了address、pv1等变量外的[]包裹,让Pandas自动将每个元素映射到单独的行,彻底解决单行显示问题。
  2. 文本清理:用replace('\n', ' ')去除网页文本中的换行符,避免\n转义字符在Excel中显示。
  3. Selenium效率优化:只初始化一次浏览器,循环结束后统一关闭,大幅提升运行效率并减少浏览器启停带来的异常。
  4. 异常处理增强:捕获具体异常信息,同时给三个列表添加空值,确保所有列表长度与邮编Series一致,避免DataFrame创建时报错。
  5. 显式等待替代固定sleep:用WebDriverWait等待元素加载,比固定时间sleep更可靠,能根据页面实际加载情况调整等待时长。

额外建议

  • 可以给Selenium添加无头模式配置,让浏览器在后台运行,进一步提升效率:
    options = webdriver.ChromeOptions()
    options.add_argument('--headless=new')
    driver = webdriver.Chrome(options=options)
    
  • 如果遇到页面结构变化导致xpath失效,可以尝试用更稳定的元素定位方式(如class name或css selector)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:53:16