MacOS下使用Selenium+ChromeDriver抓取Google Maps条目时崩溃的问题排查
MacOS下使用Selenium+ChromeDriver抓取Google Maps条目时崩溃的问题排查
我之前在MacOS上用Selenium爬Google Maps时也碰到过一模一样的ChromeDriver崩溃问题,结合你的代码来看,主要是版本兼容、无头模式配置、滚动逻辑稳定性这几个方面的问题,咱们一步步来解决:
1. 优先排查Chrome与ChromeDriver版本匹配
这是MacOS下ChromeDriver崩溃最常见的根源!Chrome的主版本号必须和ChromeDriver完全一致(比如Chrome 118.x对应ChromeDriver 118.x):
- 查看Chrome版本:打开Chrome输入
chrome://version/,记下版本号 - 给ChromeDriver加执行权限:MacOS下如果Driver没有权限会直接崩溃,执行
chmod +x chromedriver - 替换对应版本的ChromeDriver,确保和你的Chrome版本完全匹配
2. 优化无头模式与启动参数
你的无头模式配置偏旧,MacOS下无头模式默认窗口极小,会导致滚动、元素定位异常甚至崩溃,修改ChromeOptions:
options = webdriver.ChromeOptions() # 用新版无头模式,稳定性远高于旧版 options.add_argument("--headless=new") options.add_argument("--window-size=1920,1080") # 必须添加,模拟正常桌面窗口大小 options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-gpu') # MacOS下禁用GPU大幅降低崩溃概率 options.add_argument('--disable-extensions') # 关闭扩展,减少资源占用 options.add_argument('--blink-settings=imagesEnabled=false') # 可选:禁用图片加载,提升爬取速度
3. 修复动态滚动逻辑
你的滚动逻辑依赖单个元素滚动,容易触发StaleElementReferenceException,而且没有定位到Google Maps的官方滚动容器,导致滚动不彻底甚至崩溃,修改滚动部分代码:
wait = WebDriverWait(browser, 15) # 定位Google Maps的结果列表容器(这个容器滚动比单个元素稳定10倍) results_container = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div[role='feed']"))) SCROLL_PAUSE = 3 STUCK_LIMIT = 8 last_height = browser.execute_script("return arguments[0].scrollHeight", results_container) stuck_count = 0 while stuck_count < STUCK_LIMIT: # 直接滚动容器到底部 browser.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", results_container) time.sleep(SCROLL_PAUSE) # 检查是否加载了新内容 new_height = browser.execute_script("return arguments[0].scrollHeight", results_container) if new_height == last_height: stuck_count += 1 else: last_height = new_height stuck_count = 0 # 有新内容加载,重置计数器 # 滚动完成后重新获取所有条目,避免元素过期 entries = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, "hfpxzc")))
4. 提升元素交互的稳定性
点击条目时必须等待元素可点击,而不是仅仅“存在”,而且点击后要等详情页完全加载再提取数据,避免因元素未就绪导致的崩溃:
for entry in entries: try: # 等待条目可点击后再点击,避免未就绪元素触发异常 wait.until(EC.element_to_be_clickable(entry)).click() # 等待详情页核心元素加载完成(用更稳定的选择器) wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "h1.DUwDvf.lfPIob"))) # 开始提取数据 name = browser.find_element(By.CSS_SELECTOR, "h1.DUwDvf.lfPIob").text.strip() # 你的其他数据提取逻辑... except StaleElementReferenceException: # 元素过期时,重新获取条目列表并跳过当前循环 entries = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, "hfpxzc"))) continue except Exception as e: print(f"处理条目时出错: {str(e)}") continue # 所有条目处理完成后再关闭浏览器 browser.quit() return pois
5. 其他注意事项
- 避免频繁创建销毁浏览器:如果函数会被多次调用,建议复用浏览器实例,减少资源占用
- 增加随机等待:在滚动、点击后添加2-5秒的随机等待时间,避免触发Google Maps的反爬机制,也能提升稳定性
- 检查权限:确保你的Python进程有足够的系统权限,MacOS下避免用root用户运行,可能触发沙箱限制
按照上面的步骤修改后,ChromeDriver崩溃的问题应该就能解决了,我自己在MacOS上爬Google Maps时,用这套配置稳定运行了很久。
内容来源于stack exchange
相关产品推荐
相关产品推荐

