sitemap.xml 自动向百度站长平台推送链接。然而,脚本运行后,出现了一个诡异的现象:终端显示 API 接口调用成功,剩余配额扣除了,但“成功推送条数”却是 0。
🚀 百度反馈结果:
🎉 成功推送: 0 条
📅 今日剩余配额: 10
明明我的 Sitemap 里有 90 多个链接,为什么百度一条都不收?
🔍 排查过程
我在脚本里加了一行 print 代码,打印出脚本到底抓取了什么链接。
真相瞬间大白:
👀 正在尝试推送的链接示例: http://localhost:1313/science/efficacy-liver-immunity/
原来,我推给百度的全是 localhost 的本地预览链接!
百度蜘蛛肯定访问不了我家里的电脑,自然全部拒收。
💡 原因分析
这是一个 Hugo 初学者(包括我)非常容易忽视的机制:
-
当你运行 hugo server 时:
Hugo 会在内存中生成网站,为了方便本地调试,它会强制把 sitemap.xml 里的域名替换为 http://localhost:1313。
-
当你只运行 hugo 时:
Hugo 才会读取配置文件 hugo.toml 中的 baseURL(例如 https://huoshantiepifengdou.com/),生成真正的生产环境文件。
我之前的操作习惯是开着 hugo server 预览,然后直接运行 Python 脚本,读取到的自然是“假”的 Sitemap。
✅ 解决方案
第一步:修正 Hugo 配置
确保 hugo.toml 中的 baseURL 是带 HTTPS 且以斜杠结尾的标准格式:
baseURL = "[https://huoshantiepifengdou.com/](https://huoshantiepifengdou.com/)"
第二步:正确的构建流程
在运行推送脚本前,必须先生成正式文件(最好先清理一下缓存):
# 1. 清理旧文件
rm -rf public
# 2. 生成正式环境文件 (千万别加 server 参数)
hugo
# 3. 运行 Python 推送脚本
python baidu_push.py
附:优化后的 Python 推送脚本
如果你也需要这个功能,这是我修复 SSL 警告并增加了配额限制的最终版脚本:记得将配置区域的BAIDU_TOKEN换成你的哦。
import requests
import xml.etree.ElementTree as ET
import os
# ================= 配置区域 =================
# 1. 您的网站域名
SITE_URL = 'https://huoshantiepifengdou.com'
# 2. 您的百度准入密钥 (保持您原来的 Token 不变)
BAIDU_TOKEN = '您的百度准入密钥'
# 3. Sitemap 文件路径
SITEMAP_FILE = 'public/sitemap.xml'
# 4. ⚠️ 每日最大推送数量限制 (新站建议设为 10 或 20)
# 百度普通收录配额:新站通常只有 10-100 条/天
MAX_PUSH_LIMIT = 10
# ===========================================
def get_urls_from_sitemap(file_path):
"""从 sitemap.xml 中提取 URL"""
if not os.path.exists(file_path):
print(f"❌ 错误:找不到文件 {file_path}")
return []
urls = []
try:
tree = ET.parse(file_path)
root = tree.getroot()
namespace = {'ns': 'http://www.sitemaps.org/schemas/sitemap/0.9'}
for url in root.findall('ns:url', namespace):
loc = url.find('ns:loc', namespace).text
if loc:
urls.append(loc)
print(f"✅ Sitemap 中共有 {len(urls)} 个链接。")
return urls
except Exception as e:
print(f"❌ 解析 Sitemap 失败: {e}")
return []
def push_to_baidu(urls):
"""将 URL 推送到百度 API"""
if not urls:
print("⚠️ 没有链接需要推送。")
return
# 截取前 N 个链接进行推送
urls_to_push = urls[:MAX_PUSH_LIMIT]
# 👉 加上这一行,看看推的第一个链接长啥样
print(f"👀 正在尝试推送的链接示例: {urls_to_push[0]}")
print(f"✂️ 为防止超额,本次仅推送前 {len(urls_to_push)} 条链接...")
api_url = f'http://data.zz.baidu.com/urls?site={SITE_URL}&token={BAIDU_TOKEN}'
headers = {
'User-Agent': 'curl/7.12.1',
'Content-Type': 'text/plain'
}
try:
response = requests.post(api_url, headers=headers, data='\n'.join(urls_to_push))
result = response.json()
print("\n🚀 百度反馈结果:")
if 'success' in result:
print(f"🎉 成功推送: {result['success']} 条")
print(f"📅 今日剩余配额: {result['remain']}")
else:
# 打印详细错误
print(f"⚠️ 推送失败: {result}")
if result.get('error') == 400 and result.get('message') == 'over quota':
print("💡 提示:今日配额已用完,请明天再试,或降低 MAX_PUSH_LIMIT。")
except Exception as e:
print(f"❌ 网络请求失败: {e}")
if __name__ == '__main__':
print("--- 开始执行百度 SEO 主动推送 (安全模式) ---")
# 1. 获取所有链接
all_urls = get_urls_from_sitemap(SITEMAP_FILE)
# 2. 执行受限推送
if all_urls:
push_to_baidu(all_urls)
print("\n--- 执行完毕 ---")
🎯 总结
技术路上全是细节。
hugo server 是给博主看的,hugo 是给搜索引擎看的。
搞清楚这个区别,SEO 自动化之路才能走得通。