如何获取给定关键词的Google真实搜索结果数量?
解决方案:规避reCAPTCHA并高效获取Google真实搜索结果数
我完全理解你的痛点——Google展示的虚假结果数和频繁的reCAPTCHA确实把批量查询搞得头大,尤其是你需要精确匹配的真实计数来排序主题重要性。下面从优化Selenium、规避检测、替代API三个方向给你可行的方案:
一、先优化脚本逻辑:大幅减少请求次数
你的原脚本逐页请求的方式太低效,而且容易触发检测。其实可以直接跳到接近真实结果数的页面,把请求从十几页压缩到2-3次,大幅降低被识别的概率。
修改后的核心逻辑示例:
def search_result_count(s): query = url_encode(s) # 获取首页初始虚假计数 Firefox.get(BASE_SEARCH.format(query, 0)) result_stats = Firefox.find_element(by='id', value='result-stats').text init_count = int([x.replace(',', '') for x in result_stats.split() if x.replace(',', '').isdigit()][0]) # 直接跳转到大概率是最后一页的位置(根据你的案例,真实计数大多在200以内) guess_start = min(init_count, 200) Firefox.get(BASE_SEARCH.format(query, guess_start)) current_stats = Firefox.find_element(by='id', value='result-stats').text current_count = int([x.replace(',', '') for x in current_stats.split() if x.replace(',', '').isdigit()][0]) # 验证前一页是否还是初始虚假计数,确认真实值 if current_count != init_count: prev_start = guess_start - 100 Firefox.get(BASE_SEARCH.format(query, prev_start)) prev_count = int([x.replace(',', '') for x in Firefox.find_element(by='id', value='result-stats').text.split() if x.replace(',', '').isdigit()][0]) return current_count if prev_count == init_count else prev_count else: # 极少数情况真实计数超过200,再尝试更大的start值 guess_start += 200 Firefox.get(BASE_SEARCH.format(query, guess_start)) return int([x.replace(',', '') for x in Firefox.find_element(by='id', value='result-stats').text.split() if x.replace(',', '').isdigit()][0])
二、彻底规避reCAPTCHA的Selenium配置
原生Selenium很容易被Google检测,推荐使用undetected-chromedriver替代,它专门针对Google的反爬机制做了指纹伪装,配合随机UA和延迟,基本可以避免验证。
步骤1:安装依赖
pip install undetected-chromedriver
步骤2:优化后的完整代码
import undetected_chromedriver as uc from string import ascii_letters, digits import random import time # 真实用户代理池,每次请求随机切换 USER_AGENTS = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' ] def url_encode(s): valid = digits + ascii_letters query = '' for c in s: if c in valid: query += c elif c == ' ': query += '+' else: query += ''.join(f'%{b:02X}' for b in c.encode('utf8')) return query BASE_SEARCH = 'https://www.google.com.hk/search?q=%22{}%22&gl=us&hl=en&pws=0&start={}&num=100' # 初始化伪装后的Chrome浏览器 options = uc.ChromeOptions() options.headless = True options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument(f"user-agent={random.choice(USER_AGENTS)}") driver = uc.Chrome(options=options) def search_result_count(s): query = url_encode(s) # 首页请求,模拟人类延迟 driver.get(BASE_SEARCH.format(query, 0)) time.sleep(random.uniform(1.5, 3.0)) # 鲁棒提取结果数(避免about位置变化的问题) result_stats = driver.find_element(by='id', value='result-stats').text init_count = int([x.replace(',', '') for x in result_stats.split() if x.replace(',', '').isdigit()][0]) # 跳转到猜测的最后一页 guess_start = min(init_count, 200) driver.get(BASE_SEARCH.format(query, guess_start)) time.sleep(random.uniform(1.0, 2.5)) current_stats = driver.find_element(by='id', value='result-stats').text current_count = int([x.replace(',', '') for x in current_stats.split() if x.replace(',', '').isdigit()][0]) # 验证并返回真实计数 if current_count != init_count: prev_start = guess_start - 100 driver.get(BASE_SEARCH.format(query, prev_start)) time.sleep(random.uniform(1.0, 2.5)) prev_count = int([x.replace(',', '') for x in driver.find_element(by='id', value='result-stats').text.split() if x.replace(',', '').isdigit()][0]) return current_count if prev_count == init_count else prev_count else: guess_start += 200 driver.get(BASE_SEARCH.format(query, guess_start)) time.sleep(random.uniform(1.0, 2.5)) return int([x.replace(',', '') for x in driver.find_element(by='id', value='result-stats').text.split() if x.replace(',', '').isdigit()][0])
三、免费替代API方案(适合超大量查询)
如果需要批量查询上千个关键词,即使优化Selenium也可能触发频率限制,推荐使用Brave Search API:
- 支持精确匹配(双引号语法和Google一致)
- 返回的结果计数是真实值
- 免费额度为每天1000次请求,完全满足你的需求
示例代码:
import requests # 注册Brave Search API获取免费密钥 BRAVE_API_KEY = "你的API密钥" def brave_search_count(s): encoded_query = url_encode(f'"{s}"') url = f"https://api.search.brave.com/res/v1/web/search?q={encoded_query}&count=1" headers = {"Accept": "application/json", "X-Subscription-Token": BRAVE_API_KEY} response = requests.get(url, headers=headers) data = response.json() return data.get("estimatedResults", 0)
注:Brave的结果数和Google略有差异,但对于主题重要性排序的相对值来说,完全可靠。
四、批量查询的额外注意事项
- 随机请求间隔:设置5-10秒的随机延迟,避免触发频率限制
- 缓存结果:对重复查询缓存结果,减少不必要的请求
- IP轮换:如果请求量极大,可搭配免费代理池(或付费代理)进一步降低被限制的概率
内容的提问来源于stack exchange,提问作者Ξένη Γήινος
相关产品推荐
相关产品推荐

