如何使用Selenium和Python爬取Google People Also Ask板块问答
稳定定位方案
绝对XPath失效的核心原因是谷歌搜索页会根据搜索关键词、用户地区、访问设备动态调整上层DOM节点的顺序和层级,完全依赖节点位置的定位方式必然不通用。你可以改用基于节点特征属性的相对XPath/CSS选择器定位,不受上层结构变化影响:
核心改造思路
- 跳过上层不稳定的div节点,直接定位
People Also Ask板块下的所有问答对元素,谷歌对该类元素设置了长期不变的特征类名related-question-pair - 每个问答对内部的问题、答案节点也用固定属性定位,不要写死层级
改造后代码示例
首先导入需要的模块,然后修改定位逻辑:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 初始化浏览器的代码自行补充,注意设置合规user-agent避免被反爬拦截 driver = webdriver.Chrome() def get_all_paa_qa(need_count=5): qa_list = [] # 等待PAA板块加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "div.related-question-pair")) ) # 获取所有问答对元素 paq_items = driver.find_elements(By.CSS_SELECTOR, "div.related-question-pair") # 取前need_count个有效结果 for item in paq_items[:need_count]: try: # 定位问题元素 question_ele = item.find_element(By.CSS_SELECTOR, "span.CSkcDe") question = question_ele.text.strip() if not question: continue # 点击展开问题,否则答案默认隐藏无法获取完整内容 question_ele.click() time.sleep(0.5) # 等待答案渲染完成 # 定位答案元素 answer_ele = item.find_element(By.CSS_SELECTOR, "div.kb0PBd") answer = answer_ele.get_attribute('outerHTML') qa_list.append({"question": question, "answer": answer}) except Exception as e: print(f"单条问答爬取失败: {str(e)}") continue return qa_list if __name__ == '__main__': driver.get("目标谷歌搜索链接") # 爬取前5条问答 qa_result = get_all_paa_qa(need_count=5) print(qa_result) driver.quit()
补充优化点
- 如果遇到类名迭代更新的情况,可以把CSS选择器换成基于属性的XPath,比如定位问答对可以写成
//div[contains(@jsname, "N760b")],jsname属性比类名稳定性更高 - 可以补充页面滚动逻辑,部分场景下PAA板块默认只显示3条,滚动到页面底部会触发加载更多内容
- 点击展开问题后可以用显式等待判断答案加载完成,替换固定sleep语句,提升爬取效率
内容的提问来源于stack exchange,提问作者nguyenphanhoaiduc
相关产品推荐
相关产品推荐

