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

Selenium自动化Python(Web Scraping):解决Chrome页面自动刷新导致抓取中断及耗时过长问题

Selenium自动化Python(Web Scraping):解决Chrome页面自动刷新导致抓取中断及耗时过长问题

嘿,我之前做Python爬虫时也碰到过一模一样的糟心事——Chrome自动刷新打断抓取流程不说,整个过程慢得让人抓狂!给你分享几个我亲测有效的解决方案,分两部分解决你的问题:


一、搞定页面自动刷新的问题

1. 直接拦截刷新请求

我最常用的方法是通过Chrome DevTools协议拦截页面的刷新请求,从根源上阻止页面重载。具体是监听网络请求,当检测到当前页面的文档请求(也就是刷新操作)时直接取消它。代码示例如下:

from selenium import webdriver

# 初始化Chrome浏览器
driver = webdriver.Chrome()
# 启用Network监控
driver.execute_cdp_cmd("Network.enable", {})

def intercept_refresh(request):
    # 匹配当前页面的GET请求(也就是刷新)
    if request['request']['url'] == driver.current_url and request['request']['method'] == 'GET':
        # 取消这个刷新请求
        driver.execute_cdp_cmd("Network.cancelRequest", {"requestId": request['requestId']})
        print("拦截了一次页面自动刷新")
    else:
        # 其他请求正常放行
        driver.execute_cdp_cmd("Network.continueRequest", {"requestId": request['requestId']})

# 设置请求拦截规则,只拦截文档类型的请求
driver.execute_cdp_cmd(
    "Network.setRequestInterception",
    {"patterns": [{"urlPattern": "*", "resourceType": "Document"}]}
)
# 添加拦截事件监听
driver.add_event_listener("Network.requestIntercepted", intercept_refresh)

2. 检测刷新后自动恢复状态

如果拦截请求的方法不生效(比如有些网站的刷新是通过JS触发的特殊请求),那就退而求其次:检测页面是否刷新,一旦发现就自动恢复到之前的抓取状态。核心是利用StaleElementReferenceException——当页面刷新后,之前定位的元素会失效,抛出这个异常。代码示例:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException

# 记录初始页面URL和关键元素的定位器
original_url = driver.current_url
target_locator = ("id", "your-target-element-id")

def check_and_recover():
    try:
        # 尝试访问关键元素,判断页面是否正常
        WebDriverWait(driver, 5).until(EC.presence_of_element_located(target_locator))
    except StaleElementReferenceException:
        # 页面刷新了,重新导航到原页面并恢复操作
        driver.get(original_url)
        # 这里可以添加你需要恢复的步骤,比如重新滚动到目标位置、点击之前的按钮等
        print("页面自动刷新了,已恢复抓取状态")

# 在抓取过程中定期调用这个检测函数
# 比如每执行几步操作就检查一次
check_and_recover()

3. 禁用页面的JS刷新逻辑

有些网站的自动刷新是通过JS的setInterval或者location.reload()实现的,我们可以直接在页面中覆盖这些函数,让它们失效:

# 覆盖window.reload函数,让它什么都不做
driver.execute_script("window.reload = function() {};")
# 清除所有已设置的定时器,防止定时刷新
driver.execute_script("""
    var maxIntervalId = window.setInterval(function(){}, 1000);
    for(var i = 0; i < maxIntervalId; i++) {
        window.clearInterval(i);
    }
""")

二、优化抓取速度,解决耗时过长问题

1. 禁用不必要的资源加载

页面加载图片、CSS、广告等资源会占用大量时间,如果你的抓取不需要这些,直接禁用它们:

from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
# 禁用图片加载
prefs = {"profile.managed_default_content_settings.images": 2}
chrome_options.add_experimental_option("prefs", prefs)
# 禁用CSS(如果页面结构不依赖CSS的话,可选)
chrome_options.add_argument("--disable-css")
# 禁用非必要的JavaScript(如果抓取不需要JS渲染数据,可选)
chrome_options.add_argument("--disable-javascript")

# 用配置好的options启动浏览器
driver = webdriver.Chrome(options=chrome_options)

2. 使用无头模式运行Chrome

无头模式下Chrome不会渲染可视化界面,速度会快很多,而且占用资源更少:

chrome_options.add_argument("--headless=new")  # 新版本Chrome推荐的无头模式
chrome_options.add_argument("--disable-gpu")  # 禁用GPU加速,避免兼容性问题

3. 替换time.sleep()为显式等待

别再用固定的time.sleep()等待了!显式等待只会等到目标元素出现再继续,能大幅减少不必要的等待时间:

# 不好的写法:不管元素是否加载完成,硬等10秒
import time
time.sleep(10)

# 推荐的写法:最多等10秒,元素出现就立刻继续
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located(("id", "target-element"))
)

4. 批量抓取用多线程/多进程

如果要抓取多个页面,单线程效率太低,可以用多线程(注意每个线程要单独初始化一个Chrome实例):

from concurrent.futures import ThreadPoolExecutor
from selenium import webdriver

def scrape_single_page(url):
    # 每个线程单独创建driver
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument("--headless=new")
    driver = webdriver.Chrome(options=chrome_options)
    driver.get(url)
    # 这里写你的抓取逻辑
    page_data = driver.find_element("tag name", "body").text
    driver.quit()
    return page_data

# 要抓取的页面列表
target_urls = ["https://example.com/page1", "https://example.com/page2", "https://example.com/page3"]

# 用线程池批量处理,max_workers根据你的机器性能调整
with ThreadPoolExecutor(max_workers=3) as executor:
    results = list(executor.map(scrape_single_page, target_urls))

print("所有页面抓取完成:", results)

备注:内容来源于stack exchange,提问作者Mayesh Mangyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 07:03:06