圆海博客-探寻心灵的宁静

您现在的位置是:首页 > 博客 > 正文

博客

搜索结果转JSON就这么简单!字段映射与清洗入库教程

2026-09-27 21:01:05博客
为什么搜索结果要转成JSON?
做SEO分析、竞品监控或者舆情跟踪的朋友,几乎都遇到过同一个问题:搜索结果页抓下来是一大坨HTML,标题、链接、摘要混在各种标签里,想统计个排名变化……

为什么搜索结果要转成JSON?

做SEO分析、竞品监控或者舆情跟踪的朋友,几乎都遇到过同一个问题:搜索结果页抓下来是一大坨HTML,标题、链接、摘要混在各种标签里,想统计个排名变化都要人工翻半天。而把搜索结果转成JSON之后,情况就完全不一样了——每条结果变成字段清晰的记录,程序可以直接读取、筛选、统计,后续入库和分析都顺理成章。

对比项 原始HTML JSON
数据结构 混杂在标签中 字段一目了然
读取方式 需要解析器逐层提取 程序直接加载
存储体积 冗余代码多 轻量精简
后续处理 二次清洗成本高 映射清洗即可入库

一条标准的搜索结果,转成JSON后大概长这样:

{
  "keyword": "代理IP 推荐",
  "results": [
    {
      "title": "如何挑选稳定的代理IP服务",
      "url": "https://example.com/article/101",
      "snippet": "挑选代理IP时要关注匿名度、延迟和IP池规模……",
      "rank": 1
    }
  ],
  "crawl_time": "2025-06-01 10:30:00"
}

五步流程总览:从网页到数据库

整个流程可以拆成五步:抓取结果 → 解析内容 → 字段映射 → 清洗去重 → 写入数据库。抓取和解析负责把页面变成原始数据,字段映射负责统一命名,清洗负责保证质量,最后一步才是落库。下面我们重点讲最容易踩坑的中间三步。

字段映射:给每个字段起一个标准的名字

不同网站的搜索结果,字段命名五花八门:有的叫 result_title,有的叫 item_name。如果直接入库,表结构会乱成一团。字段映射就是在这中间加一张“翻译表”,把所有来源的字段统一成一套命名规范:

原始字段 目标字段 含义
result_title title 结果标题
result_link url 跳转链接
result_abstract snippet 摘要描述
result_position rank 排名位置

用Python实现只需要一个字典:

FIELD_MAP = {
    "result_title": "title",       # 结果标题
    "result_link": "url",          # 结果链接
    "result_abstract": "snippet",  # 摘要描述
    "result_position": "rank",     # 排名位置
}

def map_fields(raw_item):
    """把原始字段名替换成标准字段名"""
    return {
        FIELD_MAP[key]: value
        for key, value in raw_item.items()
        if key in FIELD_MAP
    }

三条设计原则记住即可:字段名统一小写加下划线;一个字段只表达一个含义;映射表单独维护成配置文件,目标网站改版时只改配置、不动主流程。

数据清洗:把脏数据挡在数据库之外

刚解析出来的数据往往“看着能用,实则带毒”:标题里残留HTML标签、摘要混着全角空格和  、排名字段有时是字符串有时是空值。这些脏数据一旦入库,统计结果就会失真。常用的清洗动作有五类:去标签、空值兜底、格式统一、去重合并、异常筛查。

import re
from datetime import datetime

def clean_text(text):
    """去标签、合并空白、去首尾空格"""
    if not text:
        return ""
    text = re.sub(r"<[^>]+>", "", text)   # 去掉残留的HTML标签
    text = re.sub(r"\s+", " ", text)      # 多个空白合并成一个
    return text.strip()

def clean_item(item):
    item["title"] = clean_text(item.get("title"))
    item["snippet"] = clean_text(item.get("snippet"))
    # 排名统一成整数,缺失或异常补 0
    try:
        item["rank"] = int(item.get("rank", 0))
    except (TypeError, ValueError):
        item["rank"] = 0
    # 补齐抓取时间
    item["crawl_time"] = item.get("crawl_time") or \
        datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    return item

去重建议以 url 为唯一键,保留首次出现的记录:

def dedup(items):
    """按 url 去重,保留第一条"""
    seen, result = set(), []
    for item in items:
        if item["url"] and item["url"] not in seen:
            seen.add(item["url"])
            result.append(item)
    return result

写入数据库:让JSON顺利落库

清洗完成后,数据已经是干净的JSON记录,落库只需几行代码。下面以轻量的SQLite为例,其他数据库只需替换连接方式:

import sqlite3

items = dedup([clean_item(map_fields(r)) for r in raw_results])

conn = sqlite3.connect("search_results.db")
conn.execute("""
CREATE TABLE IF NOT EXISTS results (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    title      TEXT,
    url        TEXT UNIQUE,
    snippet    TEXT,
    rank       INTEGER,
    crawl_time TEXT
)
""")

conn.executemany(
    "INSERT OR IGNORE INTO results (title, url, snippet, rank, crawl_time) "
    "VALUES (:title, :url, :snippet, :rank, :crawl_time)",
    items,
)
conn.commit()
conn.close()
print(f"成功入库 {len(items)} 条记录")

两个实用细节:给 url 加 UNIQUE 约束配合 INSERT OR IGNORE,重复数据在数据库层面也会被自动挡住;每次入库后抽样 SELECT 几条看看,确认字段没有串位。

采集稳定,清洗入库才有意义

很多朋友流程写得没问题,却卡在第一步:搜索结果采集量大、频率高,同一个IP反复请求,很快就会被目标站点限流甚至拦截,后面映射清洗做得再好也无米下锅。想让数据持续稳定地进来,IP层面必须做好准备。

这方面可以了解光络云的动态住宅代理:基于真实住宅IP资源,支持高匿名访问与IP自动轮换,让每次请求来自不同的出口,大幅降低被识别和拦截的概率,配合上面的采集脚本就能跑得又稳又久。光络云定位为全球网络基础设施及数据服务商,产品覆盖国内和海外多种代理类型。需要提醒的是,光络云的代理IP需要你自身具备海外网络环境才能使用(TikTok专线除外),在此基础上它为你提供可靠的IP资源支撑。

常见问题

Q: 不会写代码,也能把搜索结果转成JSON吗?
可以。不少采集工具都支持把抓取结果直接导出为JSON文件,在导出设置里选择JSON格式即可。想长期自动化入库,建议掌握一点Python基础,本文示例代码可以直接套用。

Q: 字段映射表应该怎么设计?
记住三条:字段名统一小写加下划线;一个字段只表达一个含义;映射表独立成配置文件维护,目标网站改版时只改配置、不动主流程。

Q: 清洗时最容易被忽略的问题是什么?
编码和空值。搜索结果里常混有全角空格、不可见字符和HTML实体,肉眼难以察觉,入库后却会污染统计结果。建议清洗后抽样打印检查,再用去重和长度校验兜底。

Q: 采集搜索结果时频繁被拦截怎么办?
先降低请求频率、完善请求头,再从IP层面解决:使用光络云动态住宅代理这类真实住宅IP资源,配合高匿名与自动轮换,让请求更接近真实用户行为。注意使用前需自身具备海外网络环境(TikTok专线除外)。

Q: JSON和CSV该怎么选?
需要保留层级结构(比如一组关键词下嵌套多条结果)选JSON;只是简单表格、主要用Excel查看,CSV更方便。做搜索结果入库,通常JSON更合适,字段扩展也更灵活。