爬取英国学校PSHE数据遇空结果:如何获取邮箱及官网URL?
解决英国学校数据爬取(邮箱/官网)返回空结果的方案
问题诊断
你的代码返回空结果,核心原因集中在这几点:
- Google搜索页面结构已更新,原CSS选择器
div.yuRUbf > a无法匹配到有效结果 - 固定
time.sleep(2)的静态等待不可靠,页面未完全渲染就执行元素查找 - Headless模式下的浏览器特征容易被Google检测,导致无结果返回
优化方案及代码实现
1. 修复搜索结果链接获取逻辑
更新选择器、改用显式等待、强化浏览器反检测配置:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import re def google_search(query, num_results=10): options = Options() options.add_argument("--headless=new") # 新版headless模式,更接近真实浏览器 options.add_argument("--disable-blink-features=AutomationControlled") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") # 添加真实用户代理,避免被识别为爬虫 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") # 禁用自动化相关的标志 options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) # 隐藏webdriver标志 driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") search_url = f"https://www.google.com/search?q={query}&num={num_results}" driver.get(search_url) # 显式等待搜索结果加载完成,最长等待10秒 try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, 'div.g a[href]')) ) except Exception as e: print("搜索结果加载超时或无结果") driver.quit() return [] links = [] # 使用更稳定的CSS选择器匹配搜索结果链接 results = driver.find_elements(By.CSS_SELECTOR, 'div.g a[href]') for result in results: href = result.get_attribute('href') # 过滤掉Google的内部跳转链接 if href and not href.startswith("https://www.google.com/url?"): links.append(href) driver.quit() # 去重并限制结果数量 return list(set(links))[:num_results] def extract_emails_from_url(url, driver): try: driver.get(url) # 等待页面加载 WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.TAG_NAME, 'body')) ) page_source = driver.page_source # 正则匹配邮箱地址 email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' emails = re.findall(email_pattern, page_source) # 去重并过滤可能的无效邮箱 return list(set([email for email in emails if ".sch.uk" in email])) except Exception as e: print(f"访问{url}失败: {str(e)}") return [] # 主逻辑 query = "PSHE site:.sch.uk" school_links = google_search(query, num_results=20) # 初始化浏览器用于提取邮箱(避免重复启动) options = Options() options.add_argument("--headless=new") 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(service=Service(ChromeDriverManager().install()), options=options) driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") for i, url in enumerate(school_links, 1): print(f"\n{i}. 官网: {url}") emails = extract_emails_from_url(url, driver) if emails: print(f" 邮箱: {', '.join(emails)}") else: print(" 未找到邮箱") driver.quit()
2. 关键优化点说明
- 选择器更新:改用
div.g a[href]匹配搜索结果,适配Google当前页面结构 - 显式等待:用
WebDriverWait等待元素加载,替代不可靠的静态sleep - 反检测强化:添加真实UA、禁用自动化扩展、隐藏webdriver属性,降低被Google拦截的概率
- 邮箱提取:通过正则匹配页面源码中的邮箱,优先保留
.sch.uk后缀的学校邮箱
额外建议
- 如果仍遇到人机验证,可尝试降低请求频率,或添加随机等待时间
- 部分学校邮箱可能仅在联系页面,可在提取时自动检测并跳转至Contact Us页面
- 大量爬取时建议使用代理IP,避免IP被封禁
内容的提问来源于stack exchange,提问作者Omprakash S
相关产品推荐
相关产品推荐

