You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Google Search Console API报keys not supported 401错误

问题根因

你的401报错是多个问题叠加导致的:

  • 核心触发点:请求Search Console站点地图接口时,在URL末尾拼接了?key=API_KEY参数。该接口不支持API密钥认证方式,当请求URL携带key参数时,服务端会优先判定你使用了不被支持的认证方案,直接返回401,和你是否在请求头里传了Bearer格式的OAuth令牌无关,和返回的报错信息描述完全对应。
  • 代码逻辑bug:你定义的YOUR_ACCESS_TOKEN是main()函数内if/else分支里的局部变量,readSiteMap()方法无法稳定获取到正确的token值,大概率拿到空值、过期的旧值,也会触发认证失败。
  • 缺失校验逻辑:从本地token.json加载凭证后,你没有做有效性校验,如果本地存储的token已经过期,直接发起请求同样会返回未认证错误。
修复步骤
  1. 移除接口请求URL中的?key=API_KEY参数,该接口仅支持OAuth2令牌认证,不需要传递API key。
  2. 废弃全局变量隐式传递token的写法,直接把校验通过的凭证对象传入请求方法,彻底解决作用域导致的传值错误。
  3. 统一凭证校验逻辑:不管是加载本地存储的凭证,还是新完成授权的凭证,都先校验有效性,过期自动刷新后再发起业务请求。
修正后可运行代码
import os
import requests
from bs4 import BeautifulSoup
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from requests.structures import CaseInsensitiveDict

SCOPES = ['https://www.googleapis.com/auth/webmasters']
# 替换为你自己在Search Console中已验证的站点属性,必须和后台显示的完全一致(包含协议头、末尾斜杠)
WEBSITE = "https://你的站点地址/"
CLIENT_SECRETS_FILE = "client_secret.json"
sitemaps = []

def readSiteMap(creds):
    # 已移除URL中的key参数
    url = f"https://searchconsole.googleapis.com/webmasters/v3/sites/{WEBSITE}/sitemaps"
    headers = CaseInsensitiveDict()
    headers["Accept"] = "application/json"
    headers["Authorization"] = f"Bearer {creds.token}"
    headers["Content-Type"] = "application/json"
    
    resp = requests.get(url=url, headers=headers)
    if resp.status_code != 200:
        print("接口请求失败:", resp.json())
        return
    sitemap_data = resp.json()
    first_sitemap_path = sitemap_data['sitemap'][0]['path']

    xml_content = requests.get(first_sitemap_path).text
    soup = BeautifulSoup(xml_content, "xml")
    sitemap_tags = soup.find_all("sitemap")
    print(f"检测到的站点地图总数:{len(sitemap_tags)}")
    for sitemap_entry in sitemap_tags:
        loc_url = sitemap_entry.findNext("loc").text
        if "post" in loc_url:
            sitemaps.append(loc_url)
    print("抓取到的文章类站点地图列表:", sitemaps)

def main():
    creds = None
    # 加载本地已保存的授权凭证
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # 校验凭证有效性,无效则自动刷新或引导用户重新授权
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                CLIENT_SECRETS_FILE, SCOPES)
            creds = flow.run_local_server(port=0)
        # 把最新的有效凭证持久化存储到本地
        with open('token.json', 'w') as token_file:
            token_file.write(creds.to_json())
    # 直接传入有效凭证调用业务逻辑,避免全局变量传值问题
    readSiteMap(creds)

if __name__ == "__main__":
    main()

注意:WEBSITE变量的值必须和Search Console后台验证的属性完全匹配,比如你验证的是带www的域名就不能写不带www的,验证的是https站点就不能写http,末尾的斜杠也要和后台保持一致,否则会出现权限不足的错误。

内容的提问来源于stack exchange,提问作者MD Rahat Islam Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 09:24:16