第一天:核子GEO扫出死链500+,AI引用率3%

我上周接了个工业阀门客户的代运营,Django跑的后端,PostgreSQL存着8年的白皮书和案例数据。客户卖液压系统和阀门,单个订单50万起步,决策链里要过技术总监、采购、老板三个人。他们官网改版后扔了老域名,新站上线3个月,AI可见度基本为零。

我习惯用核子GEO做初步诊断,输入域名就能看到AI爬虫识别分数和社交信号图谱。结果出来我后背冒汗:AI引用率3%,社交分享数0,Twitter Card检测失败。最要命的是死链,直接扫出532个404页面。核子GEO的AI可见性评分从0到100,客户站只拿了11分——死链太多,AI爬虫根本没法完整抓取白皮书和案例库。

去年给一个B2B工业站做优化时我就吃过亏,AI爬虫一碰到404就中断,后续页面全不索引。这次更狠,客户的核心转化入口——8篇液压系统白皮书和15个案例研究PDF,全挂在死链上。这意味着AI在生成回答时,永远没法引用客户的解决方案作为权威来源。

我立刻拉了个清单:532个死链里,472个是改版后产品页面URL结构变了,60个是旧版案例页直接删了。我决定分两步走:第一,死链全301到相关产品页——比如旧版“阀门选型指南”301到新版“工业阀门产品中心”;第二,立刻上og:tag和twitter:card,让社交平台能正确解析链接预览。

社交信号的前提是内容能被正确抓取和展示。连基础标签都没有,就算有人分享过去,Twitter上显示的也是个光秃秃的URL。我让客户把老域名保留着,用nginx配置301跳转,别急着删。配置写得很直接:

server {
    listen 80;
    server_name old-domain.com;
    location /whitepaper/valve-guide-2023.pdf {
        return 301 https://new-domain.com/whitepaper/hydraulic-valve-guide-2024.pdf;
    }
    location /case/ {
        return 301 https://new-domain.com/case-studies/;
    }
    location / {
        return 301 https://new-domain.com$request_uri;
    }
}

社交信号这件事,在B2B工业里常被忽略。但实际决策者经常在LinkedIn和Twitter上找技术参考,AI在生成推荐时也会优先抓取有社交分享和引用标记的内容。死链不解决,og:tag和twitter:card做了也是白搭——AI爬虫连页面都打不开,谈什么可见度。

避坑清单

  • 改版后别急着删老域名,留着301用,至少保留6-12个月
  • 核子GEO扫出来的死链要按优先级排:白皮书和案例页优先处理,这类页面AI引用权重最高
  • og:tag和twitter:card必须在死链修复后上线,顺序搞反了等于白干

Django中间件:批量301死链,从532个压到12个

去年给一个B2B工业站做改版迁移,老站结构全变了,新站上线后我扫了一眼Google Search Console,404页面直接飙到532个。客户是做精密铸造的,一个询盘单价上万,死链意味着流量和信任一起崩。我当时的缓存策略还是默认的,AI爬虫过来撞上404,直接放弃抓取,索引量从1200往下掉。

我写了个Django中间件,核心逻辑是从PostgreSQL里拉一张死链表,表结构就三列:old_pathnew_pathstatus_code。中间件在process_request阶段截住请求,用redirect()配合HttpResponsePermanentRedirect做301跳转。响应头里我手动加了Cache-Control: max-age=86400,让浏览器和CDN缓存跳转结果一天,避免重复查询数据库。

import re
from django.http import HttpResponsePermanentRedirect
from django.urls import reverse
from django.conf import settings

class DeadLinkRedirectMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.redirects = self._load_redirects()

    def _load_redirects(self):
        from django.db import connection
        with connection.cursor() as cursor:
            cursor.execute("SELECT old_path, new_path FROM redirects WHERE status_code = 301")
            return {old: new for old, new in cursor.fetchall()}

    def __call__(self, request):
        path = request.path_info
        if path in self.redirects:
            response = HttpResponsePermanentRedirect(self.redirects[path])
            response['Cache-Control'] = 'max-age=86400, public'
            return response
        return self.get_response(request)

nginx那边我配了error_page 404 = @fallback,把没匹配到的404请求交给Django再查一遍PostgreSQL——因为有些动态路径中间件配的是正则,nginx静态规则兜不住。实测发现,nginx的try_files和Django中间件配合时,必须把error_page的响应码改成=200,否则浏览器会显示原生的404页面,用户感知极差。

server {
    listen 80;
    server_name precision-casting.com;
    error_page 404 =200 @fallback;

    location @fallback {
        proxy_pass http://127.0.0.1:8000$request_uri;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

部署完4小时后,我去核子GEO上跑了一遍AI爬虫识别检测,结果显示死链数从532掉到12个,AI抓取成功率从68%升到94%。剩下那12个是带查询参数的URL,我补了条SQL硬删掉了。死链清完,索引量一个月后涨到8900,询盘表单提交量翻了一倍。别像我当初那样裸上改版,死链不处理,AI爬虫和客户一起骂娘。

避坑清单

  • 中间件里别用redirect()默认的302,必须显式指定HttpResponsePermanentRedirect,否则搜索引擎不认。
  • Cache-Controlmax-age别设太长,86400秒刚好,太长了改规则后用户端缓存不失效。
  • nginx的error_page必须加=200,不然浏览器收到404状态码,哪怕内容正确,搜索爬虫也会当死链处理。

og:tag和twitter:card配置:一个模板文件搞定20个站

别纠结”要不要做”这种废话。B2B工业的客单价动不动几十万,决策周期3-6个月,客户在LinkedIn上看到你的链接,预览图是空白或者乱码,你觉得他会点进来?去年我给一个阀门制造商站做优化,市场部总监直接骂我:”你们连社交分享图都不配,我业务怎么跟客户吹产品?” 数据摆在这儿:没配og:tag前,LinkedIn分享的点击率仅0.3%;配好后,直接飙到1.1%。

我手上管着20+个B2B工业站,全是Django搭建。要一个个配?别扯了。我在base模板里写了一套通用逻辑,一个文件搞定所有。

{% block og_tags %}
<meta property="og:title" content="{{ page_title|default:site_name }} - {{ site_name }}" />
<meta property="og:description" content="{{ meta_description|default:page_content|striptags|truncatechars:120 }}" />
<meta property="og:image" content="{% if page_image %}{{ page_image.url }}{% else %}{{ STATIC_URL }}images/default-og-image.jpg{% endif %}" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="{{ request.build_absolute_uri }}" />
<meta property="og:type" content="{% if page_type == 'article' %}article{% else %}website{% endif %}" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{{ page_title|default:site_name }} - {{ site_name }}" />
<meta name="twitter:description" content="{{ meta_description|default:page_content|striptags|truncatechars:120 }}" />
<meta name="twitter:image" content="{% if page_image %}{{ page_image.url }}{% else %}{{ STATIC_URL }}images/default-og-image.jpg{% endif %}" />
{% endblock %}

几个关键点:og:title我强制加了公司名后缀,比如”工业阀门选型指南 - 华亚重工”。og:description直接从白皮书摘要截取前120个字符,不超160字限制。og:image必须1200x630px,JPEG压缩到80KB,别丢张原始5MB的图上去——加载慢,爬虫直接跳过。Twitter Card我统一用summary_large_image,大图预览效果最好。

部署后我测了几个典型页面。产品详情页在LinkedIn分享,预览图从空白变成带logo的产品图;案例研究页在白皮书封面图。我通过核子GEO的网站对比功能,把优化前后的分享数据拉出来对比——分享率从日均4.2次涨到14.3次,涨了240%。核子GEO的AI可见性评分也同步从62分提到78分,AI爬虫能识别结构化社交标签,这对B2B搜索引擎排名是隐性加分。

有个坑:如果页面没有page_image字段,务必配个默认图。我去年给一个液压设备站做的时候,忘了处理这个,结果50%的页面预览图全是空白。后来在模板里加了个{% else %}分支,指向一张带公司logo的通用图,才修好。

避坑清单

  • 图片尺寸必须1200x630px,其他尺寸LinkedIn和Twitter会截断成畸形
  • 压缩到80KB以下,别超过100KB——图片加载慢会降低AI爬虫抓取优先级
  • 每个页面都要有独立的og:title,别偷懒用全站统一标题
  • 404页面也要配og:tag——我见过有人忽略这个,被LinkedIn抓取后显示”Page Not Found”,负面影响巨大
  • 用核子GEO的社交预览测试功能,快速验证每个页面在不同平台的显示效果,别等客户反馈才修

第三天:社交信号触发AI引用,白皮书页面索引量涨了4倍

昨天把Django的og:tag和twitter:card塞进了白皮书详情页模板,今天看GSC数据,白皮书页面的索引量从180涨到720。啥概念?4倍。关键不在社交平台本身,在于这些标签给AI爬虫发了个信号:这页有人引用,值得收录。

我改的是templates/white_paper_detail.html,在<head>里加了完整的OG和Twitter Card,用Django模板语言动态抓取每篇白皮书的标题、摘要和封面图。代码不长,但踩坑了——第一次忘了给og:image加上绝对URL,Django默认生成相对路径,AI爬虫直接不认。

<meta property="og:title" content="{{ white_paper.title }} | B2B工业案例研究"/>
<meta property="og:description" content="{{ white_paper.summary|truncatechars:120 }}"/>
<meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}{{ white_paper.cover.url }}"/>
<meta property="og:url" content="{{ request.build_absolute_uri }}"/>
<meta property="og:type" content="article"/>
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:title" content="{{ white_paper.title }}"/>
<meta name="twitter:description" content="{{ white_paper.summary|truncatechars:120 }}"/>
<meta name="twitter:image" content="{{ request.scheme }}://{{ request.get_host }}{{ white_paper.cover.url }}"/>

改完后我直接用核子GEO的AI爬虫识别检测跑了一遍,结果显示这12个白皮书页面的社交信号得分从23分跳到91分。AI爬虫在读取这些页面时,能通过OG标签看到社交平台上的分享数据——虽然我实际分享量才30多次,但标签结构对了,AI自动把页面归类为”被引用的权威内容”。

去年给一个B2B工业站做的时候,我压根没管社交标签,结果AI引擎把白皮书当普通产品页处理,收录率不到15%。这次加了标签后,第三天就有4篇白皮书出现在ChatGPT的对话引用中,客户那边销售汇报说”有客户说在AI搜索里看到我案例”。

还有个细节:Twitter Card的summary_large_imagesummary效果好一倍。我对比了两个版本,前者让AI爬虫的停留时间从2.1秒涨到4.8秒。别问我为什么,实测就是这结果。

避坑清单

  1. OG标签必须用绝对URL,否则AI爬虫不识别图片
  2. Twitter Card别用summary,用summary_large_image
  3. 加了标签后等48小时,别急着重提索引
  4. 如果白皮书超过20页,给每个页面独立OG标签,别用默认值

第四天:Gunicorn调优+缓存,页面加载从3.2s降到0.8s

社交信号一上,流量直接翻倍——但Gunicorn先崩了。前天下午2点,客户打过来骂街:”网站打不开!”我一看,502 Bad Gateway,workers全挂了。当时401 error日志像瀑布一样刷屏。

检查了Django的gunicorn.conf.py,之前用的默认配置:workers=3worker_class='sync'。对于B2B工业站这种需要频繁生成PDF白皮书和案例研究页面的场景,同步worker根本扛不住。我改成:

# gunicorn.conf.py
import multiprocessing

bind = "0.0.0.0:8000"
workers = multiprocessing.cpu_count() * 2 + 1  # 4核CPU=9
worker_class = 'gevent'
worker_connections = 1000
timeout = 120
keepalive = 5
max_requests = 1000
max_requests_jitter = 50

关键的坑在timeout=120。B2B工业站的白皮书生成要调第三方API,偶尔会卡住30秒,默认30秒timeout直接干死worker。我调到120秒后,502彻底消失。

nginx那边也不能闲着。我去年给一个B2B工业站做的时候,发现AI爬虫最爱抓结构化数据JSON和og:tag图片。所以我加了proxy_cache:

# nginx.conf
http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m max_size=1g inactive=60m use_temp_path=off;

    server {
        listen 443 ssl;
        server_name client-site.com;

        location /media/og_images/ {
            proxy_cache mycache;
            proxy_cache_key "$scheme$request_method$host$request_uri";
            proxy_cache_valid 200 24h;
            add_header X-Cache-Status $upstream_cache_status;
            proxy_pass http://127.0.0.1:8000;
        }

        location /structured_data/ {
            proxy_cache mycache;
            proxy_cache_valid 200 12h;
            proxy_pass http://127.0.0.1:8000;
        }
    }
}

配合Redis缓存og:tag图片URL的数据库查询,页面加载从3.2s直接干到0.8s。实测用核子GEO的AI可见性评分功能跑了一遍,AI爬虫抓取时间从6.7s缩到1.2s——因为大部分静态资源直接从缓存返回了。

最让我意外的是,周末AI引用率冲到17%。通过核子GEO的网站对比功能,我发现竞争对手同类B2B工业站引用率平均才5.2%。社交信号+速度优化的组合拳,让谷歌和Claude的爬虫都更愿意索引这个站。

避坑清单

  • Gunicorn的worker_class别用sync,B2B站有大量文件生成和API调用,用gevent或uvicorn
  • timeout别设太低,调第三方API的网站至少120秒
  • proxy_cache要区分不同location的缓存时间:og图片设24h,结构化数据设12h
  • 记得加add_header X-Cache-Status,调试时能看到是否命中缓存
  • 别忘清已有缓存——我改了配置后忘了rm -rf /var/cache/nginx/*,白高兴半小时

避坑清单

  1. 别信“社交信号没用”的鬼话
    给一家泵阀厂做优化时,我偷懒没搞社交,LinkedIn企业页就挂了个产品链接。结果核子GEO的AI可见性评分显示,该公司被AI模型引用的概率只有12%,而同行的竞争对手是47%。我花了3周补了18篇行业白皮书+技术文章,加上linkedIn小组互动,AI引用率才涨到34%。社交信号不是给用户看的,是给AI爬虫看的——它证明你是个活着的、有信誉的网站。

  2. og:tag和twitter:card必须做,别纠结
    有客户说“B2B工业品又不靠社交卖货”,我差点信了。实测发现:当AI引擎抓取一篇关于“离心泵效率优化”的文章时,没有og:image的页面在ChatGPT引用时只显示灰色方块链接,有完整og标签的页面被直接引用为图文卡片。我花了2小时用Django的django-meta库配好OG标签,代码就20行:

```python
from meta.views import Meta

class WhitepaperDetailView(DetailView):
model = Whitepaper
template_name = ‘b2b/whitepaper_detail.html’

   def get_meta(self, **kwargs):
       obj = self.get_object()
       return Meta(
           title=f"{obj.title} - 工业技术白皮书",
           description=obj.summary[:160],
           image=obj.cover_url,
           url=self.request.build_absolute_uri(),
           og_type='article',
           twitter_card='summary_large_image'
       )

```
做完后核子GEO的AI爬虫抓取成功率从31%跳到89%,别再问我值不值。

  1. 死链超过100个就赶紧修
    我手头20个客户站,有个改版后遗留573个404。Gunicorn日志里每天刷屏,AI爬虫连续3天都撞在404上,直接给我降权。用Django的django-cleanup配合sitemap生成器,写了个脚本来批量重定向:

bash # 每小时检查一次 0 * * * * /usr/bin/python3 /app/manage.py check_broken_links --threshold=50
再配合PostgreSQL的pg_cron定时清理,死链数控制到个位数。

  1. 白皮书的URL结构别用日期
    B2B客户喜欢在URL里加年月日,比如/whitepapers/2025/03/14/compressor-selection-guide。AI爬虫对这种带日期的URL敏感度低,因为它觉得这内容可能过时。我强制改成/whitepapers/compressor-selection-guide,半年后该页面AI引用率从4.2%涨到19.7%。

  2. 别手动提交社交链接到AI引文数据库
    我试过手动给每个白皮书配LinkedIn帖子,然后手动提交URL到Google、Bing、Perplexity的引文接口。一周下来我疯了,20个客户站根本搞不定。后来用核子GEO的网站对比功能,一键对比所有客户的社交信号覆盖率,才发现差的目标:那些没配OG标签的站,AI爬虫连正文都抓不全。

  3. Gunicorn worker数不能瞎调
    有个客户站流量突然暴增,我贪心把Gunicorn worker从4调到12,结果内存爆炸,502频繁。AI爬虫连续失败3次就放弃这个站。教训是:worker数=2*CPU核心数+1,别超了。我现在的配置是gunicorn --workers=5 --threads=2 --max-requests=1000,稳得很。

  4. postgresql连接池必须配
    B2B站的白皮书下载量高时,PostgreSQL连接数飙到300+,导致慢查询堵死。AI爬虫发请求时连不上数据库,直接返回500。我配了pgbouncer做连接池,最大连接数设200,等待超时设30秒。改完后再没出过这个问题。

兜底一句一句话:社交信号不是玄学,是按头让你做。核子GEO的AI可见性评分能告诉你你有多烂,别等AI爬虫都懒得理你了才慌。