Django中如何查询谷歌网页关键词排名?避免IP封禁与验证码方案
如何在Django应用中实现谷歌关键词排名查询(避开封禁与验证码)
嘿,我来帮你梳理下怎么搞定这个功能——谷歌的反爬机制确实严格,但只要模拟真实用户行为、控制请求节奏,就能顺利实现你的需求。针对你提到的www.onet.pl和关键词wiadomości的场景,我给你拆解具体步骤:
一、先搞懂谷歌搜索请求的正确姿势
谷歌的搜索URL是有固定格式的,针对波兰地区的搜索(适配你的示例),要带上语言、地区参数,确保结果准确:
from urllib.parse import quote # 对波兰语关键词做URL编码,避免乱码 keyword = "wiadomości" encoded_keyword = quote(keyword) # 构建搜索URL:指定关键词、返回100条结果、波兰语/波兰地区 search_url = f"https://www.google.pl/search?q={encoded_keyword}&num=100&hl=pl&gl=pl"
num=100能一次性获取更多结果,减少请求次数,降低被封概率hl=pl和gl=pl确保谷歌返回波兰地区的本地化结果,和用户实际搜索的场景一致
二、伪装请求,让谷歌认为你是真实用户
直接用默认请求头会被秒识别成爬虫,必须带上真实的浏览器信息,最好随机切换:
import random # 收集几个主流浏览器的最新User-Agent,多备几个更安全 user_agents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" ] # 组装请求头,模拟波兰用户的浏览器环境 headers = { "User-Agent": random.choice(user_agents), "Accept-Language": "pl-PL,pl;q=0.9", "Referer": "https://www.google.pl/" # 模拟从谷歌主页跳转过来 }
三、控制请求频率,绝对不能“刷屏”
谷歌对请求频率非常敏感,短时间内多次请求直接触发封禁或验证码。每次查询后一定要加随机延迟:
import time # 每次请求后随机延迟15-25秒,别固定时间,更像真实用户 time.sleep(random.randint(15, 25))
四、解析搜索结果,提取目标网站的排名
谷歌的搜索结果是静态HTML,可以用BeautifulSoup解析。注意谷歌的结果链接是跳转链接,要提取真实的目标URL:
from bs4 import BeautifulSoup import requests def get_google_rank(target_domain, keyword): encoded_keyword = quote(keyword) search_url = f"https://www.google.pl/search?q={encoded_keyword}&num=100&hl=pl&gl=pl" headers = {"User-Agent": random.choice(user_agents)} try: # 发起请求,设置超时避免卡住 response = requests.get(search_url, headers=headers, timeout=10) response.raise_for_status() # 如果请求失败(比如403)直接抛出异常 soup = BeautifulSoup(response.text, "html.parser") # 找到所有带链接的结果项 result_links = soup.find_all("a", href=True) rank = None # 遍历结果,从第1条开始计数 for index, link in enumerate(result_links, start=1): real_link = link["href"] # 处理谷歌的跳转链接:真实URL在/url?q=后面,&之前 if real_link.startswith("/url?q="): real_link = real_link.split("/url?q=")[1].split("&")[0] # 检查是否包含目标域名 if target_domain in real_link: rank = index break return rank if rank else "未进入前100名" except Exception as e: print(f"查询出错:{str(e)}") return None # 调用示例:查询onet.pl在wiadomości关键词下的排名 rank = get_google_rank("onet.pl", "wiadomości") print(f"排名:{rank}")
五、进阶:彻底避开验证码的方案
如果你的查询量较大,或者遇到频繁验证码,推荐两个更可靠的方式:
1. 谷歌自定义搜索API(官方方案,最安全)
谷歌提供的官方API,完全不会被封,有免费额度(每天100次),超过后付费。需要先在谷歌云控制台创建项目,启用自定义搜索API,获取API密钥和搜索引擎ID:
def get_rank_via_google_api(target_domain, keyword): API_KEY = "你的谷歌API密钥" SEARCH_ENGINE_ID = "你的自定义搜索引擎ID" encoded_keyword = quote(keyword) api_url = f"https://www.googleapis.com/customsearch/v1?q={encoded_keyword}&cx={SEARCH_ENGINE_ID}&key={API_KEY}&num=100" response = requests.get(api_url) data = response.json() rank = None if "items" in data: for index, item in enumerate(data["items"], start=1): if target_domain in item["link"]: rank = index break return rank if rank else "未进入前100名"
2. 无头浏览器(模拟真实用户操作)
如果遇到验证码,可以用Playwright或Selenium模拟浏览器的滚动、点击等行为,但这种方式资源消耗大,一定要配合代理和延迟使用。
六、Django应用集成建议
- 异步执行查询:查询是耗时操作,别在Django的请求响应周期里同步执行,用Celery做成异步任务,或者用Django 3.1+的异步视图。
- 缓存结果:用Django的缓存框架缓存排名结果,比如每隔6小时刷新一次,减少请求次数。
- 日志记录:记录每次查询的时间、IP、结果、是否成功,方便排查问题。
内容的提问来源于stack exchange,提问作者killerbees
相关产品推荐
相关产品推荐

