外贸独立站3类页面合格度,怎么用脚本一次跑完

给外贸独立站做内容改版,最容易卡在验收:产品页的参数补全了没有、文章页能不能答上标题那个问题、问答页有几条。这些判断过去都靠人眼看,改完一批就没人再回头看一遍。

这篇把三类页面的判断标准写成可计算的指标,配一段能跑的脚本。

先说清定位。这些指标是启发式的自检工具,用来发现问题与看趋势,不是任何平台的判定标准,也不能拿它的分数去对外说效果。

一、为什么要把写法变成指标

三类页面的写法要求本身很清楚:产品页的参数与认证要能被提取,文章页要有一句直接回答标题的话,问答页要有成条的问答与对应的标记。

问题在于不可持续。一次性改完可以,但产品线在增、工艺在变,半年之后没人知道哪些页面又退回去了。

变成指标之后,改版前跑一次、改完跑一次,看的是变化量而不是绝对值。这一层与外部观测是两套数据:站内的合格度是自己可控的,站外被 AI 引用与由此带来的点击都是被动接收的。

二、三个指标的定义与合格线

指标 定义 计算方式 合格线
参数可提取率 页面上的参数有多少写在文字与表格里 文字与表格中的参数条数 ÷ 全部参数条数(含图片里的) 由站点自定,建议先取当前值再看提升
标题答案匹配度 标题问句能不能在正文里找到直答句 标题关键词命中率 × 前 300 字内是否出现同义判断句 启发式打分,只用于排序
问答覆盖度 问答条目数与结构化数据标记是否对应 问句型小标题条数、问答标记条数,两者取小 标记数不少于条目数的八成

三张合格线的量纲都是自己定的。跨站比较没有意义,因为不同品类的参数密度差得很远,同一套阈值没法通用。

三、抓取与打分脚本

脚本做三件事:取回页面的 HTML、按三个指标打分、把结果写成表。抓取用 requests 加解析库就够,页面数量在几百这个量级不需要上异步。

复制代码
# page_score.py
# pip install requests beautifulsoup4
import csv, json, re
import requests
from bs4 import BeautifulSoup

# 带单位的参数写法:数值 + 单位
PARAM_WITH_UNIT = re.compile(r'\d+(?:\.\d+)?\s*(?:mm|cm|kg|g|MPa|N|h|%|\u00b0C|小时|天)')
# 问句型小标题的粗判:以疑问词开头或结尾带问号
QUESTION_HEAD = re.compile(r'^(.{2,40}?)(?:\uff1f|\?)$')
TITLE_WORD = re.compile(r'[\u4e00-\u9fa5A-Za-z]{2,}')

def fetch(url, timeout=20):
    r = requests.get(url, headers={'User-Agent':
        'Mozilla/5.0 (compatible; site-audit/1.0)'}, timeout=timeout)
    r.raise_for_status()
    return BeautifulSoup(r.text, 'html.parser')

def score_param(soup):
    """参数可提取率:文字与表格里的参数 占 全部参数(含图片替代文字)的比例"""
    text = ' '.join(t.get_text(' ', strip=True)
                    for t in soup.find_all(['p', 'li', 'td', 'th', 'h2', 'h3']))
    in_text = len(PARAM_WITH_UNIT.findall(text))
    in_alt = 0
    for img in soup.find_all('img'):
        alt = img.get('alt') or ''
        in_alt += len(PARAM_WITH_UNIT.findall(alt))
    total = in_text + in_alt
    return round(100.0 * in_text / total, 1) if total else None

def score_answer(soup, title):
    """标题答案匹配度:标题关键词在正文前 300 字里的命中率"""
    words = set(TITLE_WORD.findall(title))
    body = ' '.join(p.get_text(' ', strip=True) for p in soup.find_all('p'))
    head = body[:300]
    if not words:
        return None
    hit = sum(1 for w in words if w in head)
    return round(100.0 * hit / len(words), 1)

def score_faq(soup):
    """问答覆盖度:问句型小标题条数 与 问答标记条数"""
    qs = [h for h in soup.find_all(['h2', 'h3'])
          if QUESTION_HEAD.match(h.get_text(strip=True))]
    marked = len(soup.select('[itemtype*="Question"]'))
    return {'questions': len(qs), 'marked': marked}

def audit(urls):
    rows = []
    for kind, url in urls:
        soup = fetch(url)
        title = (soup.title.get_text(strip=True) if soup.title else '')
        rows.append({
            'kind': kind,
            'url': url,
            'param_rate': score_param(soup),
            'answer_match': score_answer(soup, title),
            'faq': score_faq(soup),
        })
    return rows

if __name__ == '__main__':
    targets = [(r[0], r[1]) for r in csv.reader(open('urls.csv', encoding='utf-8'))]
    rows = audit(targets)
    with open('score.csv', 'w', newline='', encoding='utf-8') as f:
        w = csv.DictWriter(f, fieldnames=['kind', 'url', 'param_rate', 'answer_match', 'faq'])
        w.writeheader()
        w.writerows(rows)
    print(json.dumps(rows[:3], ensure_ascii=False, indent=2))

输入是一张两张列的清单:页面类型与地址。输出是一张分数表,可以直接和上一次的结果并排比。

几个实现上的注意点。参数正则里的单位表要按自己的品类补,机械类要加公差与硬度,纺织类要加克重与幅宽。问句型小标题的粗判只看是否以问号结尾,长标题需要再截断一次。问答标记那一段按实际使用的语法调整,用 JSON-LD 的站要改成解析脚本内容。

四、把三项指标接进改版流程

接法有两种,成本都不高。

轻量做法是放在发版清单里。每次产品页或文章页改动之后跑一次,分数掉的页面回到修改列表。这套做法不需要额外的服务。我是先在自己站上挑了二十来个页面跑了一遍,把分数表存下来,隔周再跑一次,才看清哪些页面是真的在退化。

稍重一点的做法是接进构建流程,把脚本挂在部署的下一步,输出结果存成带日期的文件。这样就有了时间序列,能看出哪些页面在缓慢退化。

建议把站内分数与站外观测分开存。站内分数在代码库里跟着版本走,站外的曝光与引用另存一份,两张表靠 URL 关联,不要混成一张表,否则口径会乱。

顺带说一句元数据的处理。页面标题、meta 描述、结构化数据、图片替代文字这四类字段,脚本里都能顺手取到,建议在分数表里各占一列。它们不影响三类页面的主体分数,但退化的速度往往比正文快。

五、判读时容易踩的三个坑

第一个坑是把参数可提取率当成越高越好。把无意义的数字堆进正文也能刷高这个分数,评出来的页面反而更差。这个指标要看的是"降下来又涨回去"的变化,不是绝对值。

第二个坑是拿标题答案匹配度当结论。它是关键词级别的粗判,同义词和改写句都会漏掉,只适合用来排序,挑出最不像的几页去看一眼。

第三个坑是只跑一次就下判断。单次分数的作用有限,同一批页面连着跑四周,趋势才有信息量。这与独立站SEO 里看排名的做法一样,单日数据基本没有意义。

六、这套做法的边界

三个指标都是代理量。它们能指出"这里可能有问题",不能证明"改完就会变好"。任何把它当成绩效指标的做法都会失真。

它也不覆盖内容质量本身。一段参数写得对不对、一个工艺结论是不是过时,脚本判不了,这部分还是得有人过。脚本的作用是让人的注意力落在少数几页上,不是替代判断。

独立站搭建阶段把这三类页面的字段位置留出来,后期的分数维护成本会低很多;我们这边的站用的是 NeoGress,产品参数位与问答段在后台是对应字段,改版时脚本能直接取到,不用再去猜结构。适不适合你的项目,看团队里有没有人能固定每周跑一次。

最后一个问题:你们现在是用什么方式记录页面改版前后的变化?评论区说一下做法,我看看有没有更适合接进自动化流程的形式。

相关推荐
isfox11 小时前
Python3 协程:异步编程的核心机制与实战
python
lhbweilai11 小时前
QT项目(串口助手)
开发语言·qt
用户2986985301411 小时前
Python 将 Markdown 批量转为 HTML:单文件与目录遍历两种实现
python·html·markdown
miofly11 小时前
GitHub 今日推荐|auto-ontology:给 Agent 装上企业数据的语义索引
python·开源·github
eggwyw12 小时前
C++相交链表和反转链表详解
开发语言·c++
Wang's Blog12 小时前
Java 项目实战:交友项目 - 保存访客记录
java·开发语言·交友
青少儿编程课堂12 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园成语接龙大挑战解析
c++·python·算法·bfs·信息学竞赛
用户03321266636712 小时前
使用 Python 扁平化 PDF 文档 【附代码示例】
python
Java后端的Ai之路12 小时前
Java并发编程07-等待通知机制优化循环等待
java·数据库·python
小小张说故事12 小时前
Python 的 async def 为什么能同时跑几千个任务?拆开协程对象、await 与事件循环那次让出
后端·python