使用Selenium获取谷歌地图店铺位置部分成功部分失败的原因及解决
问题原因及解决方案
可能原因
- 元素定位器不通用:谷歌地图针对不同品牌的店铺页面,可能采用了略有差异的DOM结构,你当前使用的选择器(比如特定class)只匹配部分店铺的地址元素,像Apple、Ferrari这类品牌的地址元素可能用了不同的class或层级结构。
- 动态加载触发条件不同:部分品牌店铺的地址模块可能需要页面滚动、鼠标悬停等操作才会完全渲染,固定20秒等待不一定能覆盖这种延迟加载场景。
- 反爬机制拦截:Colab的公共IP可能被谷歌地图识别为爬虫来源,针对部分页面限制了内容返回,导致无法获取地址。
- iframe嵌套问题:少数店铺的地址信息可能嵌套在iframe中,你的代码没有处理iframe切换,导致无法定位到元素。
解决办法
1. 优化元素定位逻辑
放弃依赖单一class的选择器,改用更通用的定位方式,比如:
- 基于地址标签的文本定位:先找到包含“地址”(英文页面对应"Address")的元素,再定位其相邻的内容元素。示例代码:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待地址标签出现,然后获取相邻的内容元素 address_label = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.XPATH, "//div[text()='地址']")) ) address = address_label.find_element(By.XPATH, "./following-sibling::div").text
- 利用谷歌地图的通用数据属性:比如定位带有
data-section-id或data-item-id属性的地址容器,这类属性通常在不同页面保持一致。
2. 替换固定等待为显式等待
用WebDriverWait结合具体的元素等待条件,代替time.sleep(20),确保元素加载完成后再进行定位,示例:
# 等待地址元素可被获取,最长等待30秒 address = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.CSS_SELECTOR, "div[aria-label*='地址']")) ).get_attribute("aria-label").replace("地址: ", "")
3. 模拟人类行为规避反爬
- 添加随机延迟:在请求不同页面之间加入
time.sleep(random.randint(3, 8)),避免请求过于频繁。 - 修改User-Agent:为浏览器设置真实的用户代理,模拟普通浏览器访问:
from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") driver = webdriver.Chrome(options=options)
- 添加页面滚动操作:进入页面后执行滚动,触发动态内容加载:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(2)
4. 检查并处理iframe
如果页面存在iframe,先切换到对应iframe再定位元素:
# 等待iframe加载并切换 iframe = WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.TAG_NAME, "iframe")) ) driver.switch_to.frame(iframe) # 之后再定位地址元素 # 操作完成后切回主文档 driver.switch_to.default_content()
内容的提问来源于stack exchange,提问作者Rony R
相关产品推荐
相关产品推荐

