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

如何让Python Selenium脚本在浏览器最小化时正常运行?

问题:Chrome浏览器最小化后Selenium脚本无法正常运行

我编写了一个Python脚本,读取存储有姓名与邮政编码的input_names.csv文件,通过Selenium启动Chrome浏览器并将其最小化,随后将信息输入White Pages平台以获取对应地址和电话。但浏览器最小化后脚本无法正常运行,我尝试将等待条件从visibility_of_element_located()切换为element_to_be_clickable,问题仍未解决。

我的代码

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
import undetected_chromedriver as uc
import time
import csv
import setuptools

driver = uc.Chrome(use_subprocess=True)

def scrape_white_pages(name, zip_code):
    global driver

    driver.get("https://www.whitepages.com/person")

    try:
        # Wait for the address input field to be present and interactable
        name_input = WebDriverWait(driver, 20).until(
            EC.visibility_of_element_located((By.XPATH, '//*[@id="search-address"]'))
        )
        name_input.clear()  # Clear any existing text in the input field
        name_input.send_keys(name)

        # Wait for the zip code input field to be present and interactable
        zip_code_input = WebDriverWait(driver, 20).until(
            EC.element_to_be_clickable((By.XPATH, '//*[@id="search-location"]'))
        )
        zip_code_input.clear()  # Clear any existing text in the input field
        zip_code_input.send_keys(zip_code)

        name_input.send_keys(Keys.RETURN)

        time.sleep(3)  # Adjust sleep time as needed

        # Check if owner name and phone number elements are present
        elements = driver.find_elements("class name", "faq-question")

        WebDriverWait(driver, 10).until(EC.element_to_be_clickable(elements[0])).click()
        address = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="faq-0"]'))).text.strip()
        address = address[address.index("is") + 3:address.index(".")]

        WebDriverWait(driver, 10).until(EC.element_to_be_clickable(elements[1])).click()
        phone_number = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="faq-1"]'))).text.strip()
        phone_number = phone_number[phone_number.index("is") + 3:phone_number.index(".")]

    except Exception as e:
        print(f"An error occurred: {e}")

    return address, phone_number

def save_to_csv(data, filename='owner_info.csv'):
    with open(filename, 'a', newline='') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(data)

def main():
    names = []
    zip_codes = []
    #address = input("Enter address line 1: ")
    #zip_code = input("Enter ZIP code: ")
    with open("input_names.csv", "r") as file:
        lines = csv.reader(file)
        for line in lines:
            if line != '':
                if "Name" not in line and line[0] != "":
                    names.append(line[0])
                    zip_codes.append(line[1])
        file.close()
    counter = 0
    driver.get('https://www.google.com')
    driver.minimize_window()
    for i in names:
        name = names[counter]
        zip_code = zip_codes[counter]
        address, phone_number = scrape_white_pages(name, zip_code)
        if len(list(phone_number)) < 15:
            if address and phone_number:
                print(f"Address: {address}")
                print(f"Phone Number: {phone_number}")
                # Save data to CSV file
                save_to_csv([address, zip_code, phone_number, name[:name.index(" ")], name[name.index(" "):].replace(" ", "")])
            else:
                print("Address information not found.")
            counter += 1
        elif address and phone_number:
            print(f"Address: {address}")
            print(f"Phone Number: None Found")
            # Save data to CSV file
            save_to_csv([address, zip_code, "N/A", name[:name.index(" ")], name[name.index(" "):].replace(" ", "")])
        counter += 1
    driver.close()

if __name__ == "__main__":
    main()

解决方法

1. 替换最小化窗口为无头模式或窗口隐藏

Chrome最小化时会暂停部分元素渲染,导致Selenium无法正常定位元素。可以用以下两种方式替代:

  • 无头模式:完全不显示浏览器窗口,且保持正常渲染逻辑
    # 初始化driver前添加配置
    options = uc.ChromeOptions()
    options.add_argument('--headless=new')  # 新版无头模式,兼容性更好
    options.add_argument('--window-size=1920x1080')  # 设置固定窗口大小,避免布局异常
    options.add_argument('--disable-gpu')
    
    driver = uc.Chrome(options=options, use_subprocess=True)
    
  • 窗口移至屏幕外:保留浏览器进程但不显示在可视区域
    # 替换driver.minimize_window()为下面的代码
    driver.set_window_position(-10000, 0)
    

2. 优化元素定位与等待逻辑

  • 替换硬编码的time.sleep(3)为显式等待,等待页面结果加载完成:
    # 搜索后等待结果区域出现
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "faq-question"))
    )
    
  • 给address和phone_number设置默认值,避免异常时返回未初始化的变量:
    def scrape_white_pages(name, zip_code):
        global driver
        address = None
        phone_number = None  # 初始化默认值
        try:
            # 原有逻辑...
        except Exception as e:
            print(f"An error occurred: {e}")
        return address, phone_number
    
  • 使用更稳定的元素定位方式,比如结合placeholder属性替代ID定位:
    name_input = WebDriverWait(driver, 20).until(
        EC.element_to_be_clickable((By.XPATH, '//input[@placeholder="Name"]'))
    )
    zip_code_input = WebDriverWait(driver, 20).until(
        EC.element_to_be_clickable((By.XPATH, '//input[@placeholder="ZIP Code"]'))
    )
    

3. 规避反爬机制

White Pages会检测异常行为,最小化窗口可能被判定为爬虫。可以:

  • 在操作之间加入随机延迟,模拟人类行为:
    import random
    # 输入姓名后延迟
    time.sleep(random.uniform(0.5, 1.5))
    # 点击后延迟
    time.sleep(random.uniform(1, 2))
    
  • 控制请求频率,避免短时间内多次搜索。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:04:54