GEO 源码搭建实战:从零构建地理定向内容生成 + 搜索排名优化
本文聚焦Geo-targeted(地理定向) 内容生成型站点的源码搭建全流程,结合「Python+FastAPI+Vue3」轻量技术栈,从环境搭建、核心源码开发、内容生成优化到搜索排名(SEO)落地,实现地理定向内容自动化生成 + 搜索引擎排名优化的一体化搭建,适合本地行业站、区域内容站、地理化垂直平台的从零开发,所有代码片段可直接复用,兼顾实战性和可扩展性。

一、核心定位与技术栈选型
1. 核心定位
本次搭建的 GEO 站点核心是 **「地理标签 + 行业内容」深度融合 **,通过自动化生成符合搜索引擎规则的地理化原创内容,抢占「地域 + 关键词」的搜索排名,比如 "北京装修公司推荐""上海奶茶店加盟" 这类高转化地理长尾词。
2. 技术栈选型(轻量化、易搭建、强 SEO 适配)
| 技术层面 | 选型工具 / 框架 | 核心优势 |
|---|---|---|
| 后端服务 | Python3.9+FastAPI | 轻量高性能、接口开发高效、支持异步,适配 LLM 内容生成接口调用 |
| 前端展示 / 管理 | Vue3+Vite+Element Plus | 响应式布局(天然适配移动端)、打包速度快、Element Plus 快速搭建管理后台 |
| 数据库 | MySQL8.0 | 稳定存储地理信息、关键词、内容、SEO 数据,支持地理索引优化 |
| 内容生成 | 通用 LLM 接口(文心 / 通义 / ChatGPT) | 封装统一接口,支持多平台切换,一键生成地理化原创内容 |
| 地理信息处理 | GeoPy | 快速实现地理编码(地址→经纬度)、逆地理编码(经纬度→地址),关联地理标签 |
| 关键词 / SEO 工具 | Scrapy+5118 / 百度指数 | 爬取地理长尾关键词、分析关键词热度,指导内容生成 |
| 部署运维 | Docker+Docker-compose+Nginx | 跨环境无差异部署、Nginx 实现伪静态 / 反向代理 / HTTPS,核心适配 SEO |
| 辅助工具 | BeautifulSoup4/Requests | 辅助处理内容格式、调用第三方 SEO / 地理接口 |
3. 整体架构(四层架构,低耦合易扩展)
plaintext
┌─────────────────┐ 前端展示层:Vue3响应式页面(内容展示+地理分类+搜索)+ 后台管理系统
│ Vue3+Vite+EPlus│
└────────┬────────┘
│ 调用API接口
┌────────▼────────┐ 后端服务层:核心业务逻辑(地理处理+内容生成+SEO优化+关键词管理)
│ FastAPI核心模块 │ ├ 配置模块:全局LLM/数据库/地理配置
│ │ ├ 地理信息模块:GeoPy封装+地理标签管理
│ │ ├ 关键词模块:增删改查+权重+地理关联
│ │ ├ 内容生成模块:LLM通用接口+地理内容模板+原创性优化
│ │ ├ SEO优化模块:TDK生成+页面结构+URL优化
│ │ └ API接口层:提供前端所有调用接口
└────────┬────────┘
│ 读写数据
┌────────▼────────┐ 数据层:MySQL核心表(地理/关键词/内容/SEO/站点配置)+ 索引优化
│ MySQL8.0 │
└────────┬────────┘
│ 对接第三方服务
┌────────▼────────┐ 第三方服务层:LLM内容生成+地理编码+SEO工具+搜索引擎提交
│ 第三方接口/工具 │ ├ LLM:文心一言/通义千问/ChatGPT
│ │ ├ 地理:GeoPy/百度地图API
│ │ ├ SEO:5118/百度站长平台/谷歌搜索控制台
│ │ └ 部署:Docker镜像仓库/域名/服务器
└─────────────────┘
二、环境准备(从零初始化,一键安装依赖)
1. 本地开发环境要求
- 基础环境:Python3.9+、Node.js18+、MySQL8.0、Docker Desktop(可选,本地调试可不用)
- 工具:Git(代码管理)、Navicat/DBeaver(MySQL 管理)、VSCode(开发,安装 Vue/Python 插件)
- 服务器提前准备(后续部署用):云服务器(阿里云 / 腾讯云,2 核 4G 以上)、域名(已备案,国内必备)、HTTPS 证书(阿里云 / 腾讯云免费申请)
2. 依赖安装(直接复制配置文件,一键安装)
(1)后端依赖:requirements.txt
txt
fastapi==0.104.1
uvicorn[standard]==0.24.0.post1
pymysql==1.1.0
sqlalchemy==2.0.23
geopy==2.4.1
requests==2.31.0
beautifulsoup4==4.12.2
python-dotenv==1.0.0
scrapy==2.11.0
安装命令:pip install -r requirements.txt
(2)前端依赖:package.json(Vite+Vue3 初始化后自动生成,核心依赖已内置)
初始化前端项目命令:
bash
运行
# 创建Vue3+Vite项目
npm create vite@latest geo-front -- --template vue
# 进入项目目录
cd geo-front
# 安装Element Plus(后台管理)和路由
npm install element-plus vue-router@4
# 启动本地调试
npm run dev
3. MySQL 数据库初始化(核心表建表语句,直接执行)
新建数据库geo_seo,字符集utf8mb4,排序规则utf8mb4_unicode_ci,执行以下建表语句(包含地理、关键词、内容、SEO 核心表):
sql
-- 地理信息表:存储城市/区域/商圈,核心地理标签
CREATE TABLE `geo_info` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`geo_name` varchar(50) NOT NULL COMMENT '地理名称(如北京/朝阳区/国贸)',
`geo_level` tinyint NOT NULL COMMENT '地理级别:1-城市 2-区域 3-商圈',
`parent_id` int unsigned DEFAULT 0 COMMENT '父级ID(区域关联城市,商圈关联区域)',
`longitude` varchar(20) DEFAULT '' COMMENT '经度',
`latitude` varchar(20) DEFAULT '' COMMENT '纬度',
`industry` varchar(100) DEFAULT '' COMMENT '适配行业(多个用,分隔)',
`sort` int DEFAULT 0 COMMENT '排序',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_geo_name` (`geo_name`),
KEY `idx_geo_level` (`geo_level`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='地理信息表';
-- 关键词表:存储核心词+地理长尾词,关联地理信息
CREATE TABLE `keyword` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`keyword` varchar(100) NOT NULL COMMENT '关键词(如北京装修公司)',
`core_word` varchar(50) NOT NULL COMMENT '核心词(如装修公司)',
`geo_id` int unsigned NOT NULL COMMENT '关联地理ID',
`hot` int DEFAULT 0 COMMENT '关键词热度(5118/百度指数)',
`weight` tinyint DEFAULT 3 COMMENT '权重:1-低 2-中 3-高',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_keyword` (`keyword`),
KEY `idx_geo_id` (`geo_id`),
KEY `idx_core_word` (`core_word`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='关键词表';
-- 内容表:存储生成的地理化原创内容,核心业务表
CREATE TABLE `content` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`title` varchar(100) NOT NULL COMMENT '文章标题(符合SEO规范)',
`content` longtext NOT NULL COMMENT '文章内容(地理化+原创)',
`geo_id` int unsigned NOT NULL COMMENT '关联地理ID',
`keyword_id` int unsigned NOT NULL COMMENT '关联关键词ID',
`tdk_title` varchar(60) NOT NULL COMMENT 'SEO标题(TDK)',
`tdk_desc` varchar(160) NOT NULL COMMENT 'SEO描述(TDK)',
`tdk_key` varchar(100) NOT NULL COMMENT 'SEO关键词(TDK)',
`url` varchar(255) NOT NULL COMMENT '页面URL(伪静态)',
`status` tinyint DEFAULT 1 COMMENT '状态:1-发布 0-草稿',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_geo_id` (`geo_id`),
KEY `idx_keyword_id` (`keyword_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='内容表';
-- SEO优化表:存储页面收录/排名数据,监控SEO效果
CREATE TABLE `seo_data` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`content_id` int unsigned NOT NULL COMMENT '关联内容ID',
`keyword` varchar(100) NOT NULL COMMENT '监控关键词',
`rank` int DEFAULT 0 COMMENT '搜索引擎排名(0-未收录 1-10-首页)',
`search_engine` varchar(20) DEFAULT 'baidu' COMMENT '搜索引擎:baidu/google/sogou',
`include_status` tinyint DEFAULT 0 COMMENT '收录状态:0-未收录 1-已收录',
`include_time` datetime DEFAULT NULL COMMENT '收录时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_content_id` (`content_id`),
KEY `idx_keyword` (`keyword`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='SEO优化表';
三、核心源码开发(后端为主,前端极简,聚焦内容 + SEO)
本次开发核心是后端业务逻辑(地理处理 + 内容生成 + SEO 优化),前端仅做「后台管理(内容 / 关键词 / 地理配置)+ 前端内容展示」,无需复杂 UI,优先保证 SEO 适配。
1. 后端核心模块开发(FastAPI,项目结构)
后端项目结构(低耦合,易扩展):
plaintext
geo-back/
├── .env # 全局配置(LLM接口/数据库/地理配置)
├── requirements.txt # 依赖文件
├── main.py # 项目入口(FastAPI启动+路由注册)
├── config/ # 配置模块
│ └── settings.py # 配置读取(数据库/LLM/GeoPy)
├── geo/ # 地理信息模块
│ └── geo_service.py # GeoPy封装(地理编码/逆地理编码/地理标签)
├── keyword/ # 关键词管理模块
│ └── keyword_service.py # 关键词增删改查+地理关联
├── content/ # 内容生成模块(核心)
│ └── content_service.py # LLM通用接口+地理内容生成+原创性优化
├── seo/ # SEO优化模块(核心)
│ └── seo_service.py # TDK生成+URL优化+页面结构优化
├── models/ # 数据库模型(SQLAlchemy)
│ └── models.py # 对应MySQL表结构
└── api/ # API接口层
├── geo_api.py # 地理接口
├── keyword_api.py # 关键词接口
├── content_api.py # 内容生成/管理接口
└── seo_api.py # SEO数据/优化接口
(1)全局配置:.env + config/settings.py
-
.env(敏感信息配置,不要提交到代码仓库):env
# 数据库配置 DB_HOST=127.0.0.1 DB_PORT=3306 DB_USER=root DB_PWD=你的MySQL密码 DB_NAME=geo_seo # LLM配置(通用接口,支持文心/通义/ChatGPT,这里以通义千问为例) LLM_TYPE=qwen LLM_API_KEY=你的通义千问API_KEY LLM_API_URL=https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation LLM_TEMPERATURE=0.7 # 生成温度(0-1,越高越原创,0.7兼顾原创和逻辑) # GeoPy配置(地理编码,使用Nominatim) GEO_USER_AGENT=geo_seo_crawler # 站点配置(SEO用) SITE_DOMAIN=www.geo-seo.com # 你的域名 SITE_TITLE=地理定向内容平台 # 站点主标题 -
config/settings.py(配置读取):python
运行
from pydantic_settings import BaseSettings from dotenv import load_dotenv import os # 加载.env文件 load_dotenv() class Settings(BaseSettings): # 数据库配置 DB_HOST: str = os.getenv("DB_HOST") DB_PORT: int = int(os.getenv("DB_PORT")) DB_USER: str = os.getenv("DB_USER") DB_PWD: str = os.getenv("DB_PWD") DB_NAME: str = os.getenv("DB_NAME") # 数据库URL DB_URL: str = f"mysql+pymysql://{DB_USER}:{DB_PWD}@{DB_HOST}:{DB_PORT}/{DB_NAME}?charset=utf8mb4" # LLM配置 LLM_TYPE: str = os.getenv("LLM_TYPE") LLM_API_KEY: str = os.getenv("LLM_API_KEY") LLM_API_URL: str = os.getenv("LLM_API_URL") LLM_TEMPERATURE: float = float(os.getenv("LLM_TEMPERATURE")) # GeoPy配置 GEO_USER_AGENT: str = os.getenv("GEO_USER_AGENT") # 站点配置 SITE_DOMAIN: str = os.getenv("SITE_DOMAIN") SITE_TITLE: str = os.getenv("SITE_TITLE") # 实例化配置 settings = Settings()
(2)地理信息模块:geo/geo_service.py(GeoPy 封装,核心)
实现地址→经纬度 、经纬度→地址 、地理标签关联,为内容生成提供精准地理信息:
python
运行
from geopy.geocoders import Nominatim
from config.settings import settings
from geopy.exc import GeopyError
# 初始化GeoPy地理编码器
geolocator = Nominatim(user_agent=settings.GEO_USER_AGENT, timeout=10)
class GeoService:
@staticmethod
def geo_encode(geo_name: str) -> dict:
"""
地理编码:地址→经纬度
:param geo_name: 地理名称(如北京/朝阳区/国贸)
:return: 包含经度、纬度、地址的字典,失败返回空字典
"""
try:
location = geolocator.geocode(geo_name)
if location:
return {
"longitude": str(location.longitude),
"latitude": str(location.latitude),
"address": location.address
}
return {}
except GeopyError as e:
print(f"地理编码失败:{e}")
return {}
@staticmethod
def geo_decode(longitude: str, latitude: str) -> dict:
"""
逆地理编码:经纬度→地址
:param longitude: 经度
:param latitude: 纬度
:return: 包含地理名称、地址的字典,失败返回空字典
"""
try:
location = geolocator.reverse(f"{latitude}, {longitude}")
if location:
return {
"geo_name": location.raw.get("address", {}).get("city", "") or location.raw.get("address", {}).get("town", ""),
"address": location.address
}
return {}
except GeopyError as e:
print(f"逆地理编码失败:{e}")
return {}
# 实例化
geo_service = GeoService()
(3)内容生成模块:content/content_service.py(核心,LLM 通用接口 + 地理内容生成)
封装多平台 LLM 通用接口 (支持文心 / 通义 / ChatGPT 无缝切换),实现「地理信息 + 关键词 + SEO 规则」的内容自动化生成,保证内容的地理化、原创性、SEO 友好性:
python
运行
import requests
from config.settings import settings
from geo.geo_service import geo_service
from typing import Optional
class ContentService:
def __init__(self):
self.llm_type = settings.LLM_TYPE
self.api_key = settings.LLM_API_KEY
self.api_url = settings.LLM_API_URL
self.temperature = settings.LLM_TEMPERATURE
def _call_llm(self, prompt: str) -> Optional[str]:
"""
调用LLM接口(通用底层方法,支持多平台扩展)
:param prompt: 生成提示词
:return: 生成的内容,失败返回None
"""
try:
if self.llm_type == "qwen":
# 通义千问接口调用
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
}
data = {
"model": "qwen-turbo",
"input": {"messages": [{"role": "user", "content": prompt}]},
"parameters": {"temperature": self.temperature}
}
response = requests.post(self.api_url, json=data, headers=headers, timeout=30)
result = response.json()
return result.get("output", {}).get("text", "").strip()
# 扩展:文心一言/ChatGPT接口,按对应文档添加elif即可
elif self.llm_type == "ernie":
pass
elif self.llm_type == "gpt":
pass
return None
except Exception as e:
print(f"LLM调用失败:{e}")
return None
def generate_geo_content(self, geo_name: str, core_word: str, keyword: str, industry: str) -> Optional[str]:
"""
生成地理化原创内容(核心方法)
:param geo_name: 地理名称(如北京)
:param core_word: 核心词(如装修公司)
:param keyword: 地理长尾词(如北京装修公司推荐)
:param industry: 所属行业(如装修)
:return: 符合SEO的地理化原创内容
"""
# 1. 获取地理精准信息,丰富提示词
geo_info = geo_service.geo_encode(geo_name)
geo_detail = geo_info.get("address", geo_name)
# 2. 构造SEO友好的提示词(核心:关键词密度+地理融合+原创性+结构完整)
prompt = f"""
请以「{keyword}」为核心主题,撰写一篇{industry}行业的原创文章,要求如下:
1. 地理性:深度融合{geo_name}({geo_detail})的本地特色,加入{geo_name}本地{industry}行业政策、本地案例、区域特点;
2. SEO规则:核心词「{core_word}」和地理长尾词「{keyword}」在标题、首段、3个小标题、结尾必现,全文密度2%-8%,不堆砌;
3. 结构完整:包含标题(30-60字)、3-5个小标题(带数字,如「北京装修公司3大选择标准」)、首段引入、正文分析、结尾总结;
4. 原创性:内容独一无二,语言口语化,适合普通用户阅读,拒绝生硬模板,字数800-1500字;
5. 实用性:给{geo_name}本地用户提供具体的{industry}行业建议,比如选择技巧、避坑指南、本地推荐。
请直接输出文章内容,不要额外说明。
"""
# 3. 调用LLM生成内容
content = self._call_llm(prompt.strip())
return content
# 实例化
content_service = ContentService()
(4)SEO 优化模块:seo/seo_service.py(核心,TDK 生成 + URL 优化,SEO 基础)
实现TDK(Title/Description/Keywords)自动化生成 、伪静态 URL 生成,严格遵循搜索引擎 SEO 规范,无需人工配置,保证页面 SEO 基础达标:
python
运行
from config.settings import settings
from typing import Tuple
class SeoService:
@staticmethod
def generate_tdk(geo_name: str, keyword: str, core_word: str, industry: str) -> Tuple[str, str, str]:
"""
生成符合SEO规范的TDK(核心方法)
:param geo_name: 地理名称
:param keyword: 地理长尾词
:param core_word: 核心词
:param industry: 行业
:return: (tdk_title, tdk_desc, tdk_key)
"""
# 1. 生成SEO标题(30-60字,核心词+地理词+站点词,前置关键词)
tdk_title = f"{keyword}_2026最新攻略_{geo_name}{industry}本地推荐-{settings.SITE_TITLE}"
# 控制长度,超出截断
tdk_title = tdk_title[:60] if len(tdk_title) > 60 else tdk_title
# 2. 生成SEO描述(80-160字,包含关键词+地理词,突出实用性,吸引点击)
tdk_desc = f"【2026{geo_name}{core_word}最新推荐】为{geo_name}本地用户整理了靠谱的{geo_name}{core_word}名单,包含{geo_name}{industry}行业选择技巧、本地避坑指南、区域专属优惠,是{geo_name}用户找{core_word}的优质参考!"
tdk_desc = tdk_desc[:160] if len(tdk_desc) > 160 else tdk_desc
# 3. 生成SEO关键词(3-5个,核心词+地理词+长尾词,用,分隔)
tdk_key = f"{keyword},{geo_name}{core_word},{core_word},{geo_name}{industry},{industry}推荐"
return tdk_title, tdk_desc, tdk_key
@staticmethod
def generate_geo_url(geo_name: str, core_word: str) -> str:
"""
生成伪静态URL(SEO友好,包含地理词+核心词,小写,横杠分隔)
:param geo_name: 地理名称
:param core_word: 核心词
:return: 伪静态URL(如https://www.geo-seo.com/beijing-zhuangxiugongsi/)
"""
# URL标准化:去除特殊字符,空格换横杠,小写
geo_name_url = geo_name.replace(" ", "-").lower()
core_word_url = core_word.replace(" ", "-").lower()
# 伪静态路径:地理词-核心词/
url_path = f"{geo_name_url}-{core_word_url}/"
# 完整URL
full_url = f"https://{settings.SITE_DOMAIN}/{url_path}"
return full_url
# 实例化
seo_service = SeoService()
(5)项目入口与路由注册:main.py(FastAPI 启动)
python
运行
from fastapi import FastAPI
from config.settings import settings
from api import geo_api, keyword_api, content_api, seo_api
import uvicorn
# 初始化FastAPI
app = FastAPI(
title=f"{settings.SITE_TITLE}API接口",
description="地理定向内容生成+SEO优化接口",
version="1.0.0"
)
# 注册路由
app.include_router(geo_api.router, prefix="/api/geo", tags=["地理信息接口"])
app.include_router(keyword_api.router, prefix="/api/keyword", tags=["关键词接口"])
app.include_router(content_api.router, prefix="/api/content", tags=["内容生成接口"])
app.include_router(seo_api.router, prefix="/api/seo", tags=["SEO优化接口"])
# 根路径测试
@app.get("/")
async def root():
return {"code": 200, "msg": "GEO-SEO后端服务启动成功", "data": None}
# 启动项目
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
2. 前端极简开发(Vue3+Vite,聚焦 SEO + 管理)
前端无需复杂开发,核心实现 2 个功能,所有页面遵循 SEO 规范(响应式、TDK 可配置、无 JS 渲染阻塞):
-
后台管理系统 :基于 Element Plus 实现「地理信息管理、关键词管理、内容生成 / 发布、SEO 数据监控」,直接调用后端 API,核心代码为表单提交 + 列表查询 ,示例(内容生成表单):
vue
<!-- src/views/ContentGenerate.vue --> <template> <el-form ref="formRef" :model="form" label-width="120px" @submit.prevent="generateContent"> <el-form-item label="地理名称" prop="geoName"> <el-input v-model="form.geoName" placeholder="如北京/朝阳区" /> </el-form-item> <el-form-item label="核心词" prop="coreWord"> <el-input v-model="form.coreWord" placeholder="如装修公司/奶茶店加盟" /> </el-form-item> <el-form-item label="地理长尾词" prop="keyword"> <el-input v-model="form.keyword" placeholder="如北京装修公司推荐" /> </el-form-item> <el-form-item label="所属行业" prop="industry"> <el-input v-model="form.industry" placeholder="如装修/餐饮" /> </el-form-item> <el-form-item> <el-button type="primary" @click="generateContent">生成地理化内容</el-button> <el-button @click="resetForm">重置</el-button> </el-form-item> </el-form> <!-- 生成结果展示 --> <el-card v-if="content" title="生成结果" style="margin-top:20px"> <el-input v-model="content.title" placeholder="文章标题" style="margin-bottom:10px" /> <el-input v-model="content.tdkTitle" placeholder="SEO标题" style="margin-bottom:10px" /> <el-input v-model="content.tdkDesc" placeholder="SEO描述" type="textarea" rows="2" style="margin-bottom:10px" /> <el-input v-model="content.tdkKey" placeholder="SEO关键词" style="margin-bottom:10px" /> <el-input v-model="content.url" placeholder="页面URL" style="margin-bottom:10px" /> <el-editor v-model="content.content" style="height:500px" /> <el-button type="success" @click="publishContent" style="margin-top:10px">发布内容</el-button> </el-card> </template> <script setup> import { ref, reactive } from 'vue' import { ElMessage } from 'element-plus' import request from '@/utils/request' // 封装axios请求 const formRef = ref(null) const form = reactive({ geoName: '', coreWord: '', keyword: '', industry: '' }) const content = ref(null) // 生成内容 const generateContent = async () => { try { const res = await request.post('/api/content/generate', form) if (res.code === 200) { content.value = res.data ElMessage.success('内容生成成功') } } catch (e) { ElMessage.error('内容生成失败') } } // 发布内容 const publishContent = async () => { try { await request.post('/api/content/publish', content.value) ElMessage.success('内容发布成功') } catch (e) { ElMessage.error('内容发布失败') } } // 重置表单 const resetForm = () => { formRef.value.resetFields() content.value = null } </script> -
前端内容展示 :实现「地理分类列表、内容详情、站点搜索」,页面采用服务端渲染思想 (后端返回完整 TDK 和内容,前端直接渲染,避免 SPA 单页应用的 SEO 问题),Vite 打包时开启预渲染 ,生成静态 HTML 页面,核心优化:
- 所有页面的
<title>、<meta name="description">、<meta name="keywords">由后端 TDK 数据动态渲染; - URL 使用后端生成的伪静态地址,无
#号; - 内容详情页加入地理标签 (
<meta name="geo.placename" content="北京">、<meta name="geo.position" content="39.9042;116.4074">); - 加入面包屑导航(如「首页 > 北京 > 装修行业 > 北京装修公司推荐」),强化页面层级。
- 所有页面的
四、内容式生成核心优化(排名基础,地理 + SEO 深度融合)
生成的内容是搜索排名的核心,脱离地理标签和 SEO 规则的内容毫无价值,需在生成环节做好以下优化,保证内容「地理精准、SEO 友好、原创实用」:
1. 模板标准化:固定内容结构,适配搜索引擎抓取
所有生成的内容遵循 **「标题 + 首段引入 + 3-5 个数字小标题 + 正文分析 + 本地案例 + 结尾总结」** 结构,数字小标题(如「北京装修公司 3 大选择标准」「上海奶茶店加盟 5 大避坑指南」)提升用户体验和内容可读性,搜索引擎更偏好此类结构化内容。
2. 关键词融合策略:精准控制,不堆砌不遗漏
严格遵循SEO 关键词密度规则 (2%-8%),核心词 + 地理长尾词必须出现在标题、首段第一句、每个小标题、正文每段首句、结尾,同时自然融入 2-3 个相关长尾词(如 "北京装修公司" 融入 "北京家装公司""北京装修设计公司")。
3. 原创性优化:避免搜索引擎判定为 "AI 采集"
- 控制 LLM温度值(本次设置 0.7):0.5 以下内容模板化严重,0.8 以上内容逻辑易混乱,0.7 兼顾原创性和逻辑完整性;
- 丰富提示词:加入本地特色信息(如地理名称 + 行业政策、本地龙头企业、区域消费特点),让内容具有唯一性;
- 人工轻量修改:生成的内容可人工补充 1-2 个本地真实案例 / 数据,进一步提升原创性。
4. 地理标签强化:让搜索引擎识别页面地理属性
-
内容层面:自然融入地理下一级标签(如 "北京" 融入 "朝阳区、海淀区、国贸商圈");
-
页面层面:添加地理元标签 和Schema 地理结构化数据 ,示例:
html
预览
<!-- 地理元标签 --> <meta name="geo.placename" content="北京市" /> <meta name="geo.region" content="CN-11" /> <meta name="geo.position" content="39.9042;116.4074" /> <!-- Schema地理结构化数据(搜索引擎优先识别) --> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Place", "name": "北京市", "geo": { "@type": "GeoCoordinates", "latitude": 39.9042, "longitude": 116.4074 }, "address": { "@type": "PostalAddress", "addressLocality": "北京市", "addressCountry": "中国" } } </script>
五、搜索排名优化(SEO 核心,站内基础 + 站外提升,缺一不可)
内容生成是基础,科学的 SEO 优化才是实现搜索排名的关键 ,本次优化聚焦「地理长尾词」排名,分为站内 SEO(基础,决定是否收录) 和站外 SEO(核心,决定排名高低),所有操作严格遵循百度 / 谷歌最新 SEO 规则(2026 年),拒绝黑帽手法。
1. 站内 SEO(100% 必须做好,搜索引擎收录的前提)
站内 SEO 是自身站点的优化,可控性 100%,做好以下 6 点,保证页面100% 收录:
(1)页面 TDK 与元标签优化(核心中的核心)
-
严格遵循长度规范:Title30-60 字、Description80-160 字、Keywords3-5 个,关键词不重复;
-
TDK 唯一性:每个页面的 TDK 必须不同,避免搜索引擎判定为重复内容;
-
元标签补充:加入移动端适配、站点标识、地理标签,示例: html
预览
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <meta name="renderer" content="webkit" /> <!-- 百度适配 --> <meta name="format-detection" content="telephone=no" /> <!-- 禁止识别手机号 --> <link rel="canonical" href="https://www.geo-seo.com/beijing-zhuangxiugongsi/" /> <!-- 规范URL,避免重复收录 -->
(2)URL 与站点结构优化
- 伪静态 URL:统一使用「域名 / 地理词 - 核心词 /」格式,无动态参数(如
?id=123),搜索引擎更易抓取; - 站点层级≤3 级:「首页 > 地理分类(北京) > 行业分类(装修) > 内容详情」,层级过深会导致搜索引擎抓取不到;
- 静态资源分离:图片、CSS、JS 放在独立域名(如
static.geo-seo.com),提升页面加载速度。
(3)内链与页面结构优化
- 内链互链:相关地理内容互链(如 "北京装修公司推荐" 链接到 "北京装修设计公司"),核心关键词锚文本指向首页 / 地理专题页;
- 面包屑导航:所有页面加入面包屑,强化页面层级,帮助搜索引擎理解站点结构;
- 图片优化:图片 ALT 属性包含「地理词 + 核心词」(如
<img src="xxx.jpg" alt="北京装修公司推荐">),压缩图片大小提升加载速度。
(4)移动端适配与加载速度优化
- 响应式布局:Vue3+Vite 天然支持响应式,配合 Element Plus 的响应式组件,保证移动端体验;
- 页面加载速度:Nginx 开启 Gzip 压缩、开启静态资源缓存,内容页面图片懒加载,核心页面加载速度≤3 秒(百度核心排名指标);
- 避免 JS 阻塞:前端打包时将核心 JS 放在页面底部,静态内容优先渲染。
(5)站点地图与 Robots.txt 配置
-
生成sitemap.xml :包含所有内容页面的伪静态 URL、更新时间、优先级,提交给百度站长平台 / 谷歌搜索控制台,示例:
xml
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>https://www.geo-seo.com/beijing-zhuangxiugongsi/</loc> <lastmod>2026-02-04</lastmod> <priority>0.8</priority> </url> </urlset> -
配置robots.txt :禁止抓取无用页面(如后台管理、登录页),允许抓取核心内容,放在域名根目录(如
https://www.geo-seo.com/robots.txt),示例:plaintext
User-Agent: * Allow: / Disallow: /admin/ Disallow: /api/ Disallow: /static/js/ Sitemap: https://www.geo-seo.com/sitemap.xml
2. 站外 SEO(提升排名的关键,拉取高权重)
站内 SEO 保证收录,站外 SEO 决定排名高低,核心是通过第三方高权重平台为站点拉取「外链 + 流量 + 品牌权重」,聚焦地理长尾词排名,做好以下 4 点:
(1)高权重外链建设(核心)
- 外链平台:选择本地高权重站点 (如本地政府网、本地论坛、本地生活平台)、行业垂直站点 (如装修行业网、餐饮加盟网)、综合高权重平台(如百度百家、今日头条、知乎);
- 外链形式:软文外链(如发布《2026 北京装修公司选择指南》,文中自然插入站点链接)、签名外链(论坛 / 知乎签名档加入站点链接);
- 锚文本策略:锚文本多样化,以地理长尾词为主(如 "北京装修公司推荐"),辅以核心词(如 "装修公司")、品牌词(如 "Geo-SEO 内容平台"),避免单一锚文本被搜索引擎判定为作弊。
(2)本地平台入驻与内容分发
- 入驻本地主流平台:百度地图、高德地图、美团、大众点评(完善店铺信息,加入站点链接);
- 本地内容分发:在本地论坛(如北京贴吧、上海篱笆网)、本地自媒体(微信公众号、抖音)发布带站点链接的地理化内容,吸引本地流量。
(3)社交媒体与品牌词布局
- 社交媒体推广:在微信、抖音、小红书发布「地理 + 行业」实用内容(如短视频《北京装修避坑 3 招》),文末引导用户访问站点,提升站点流量和曝光;
- 品牌词布局:在各平台(知乎、百度知道、小红书)布局站点品牌词,回答相关问题(如 "北京装修公司推荐哪个平台?"),提升品牌权重,间接带动地理长尾词排名。
(4)友链交换(轻量补充)
与同行业 / 同地理区域的正规站点交换友链,要求对方站点:无黑帽历史、权重≥1、收录正常、无垃圾内容,友链放在站点底部,数量控制在 30 个以内。
六、Docker-compose 一键部署上线(无环境问题,适配生产)
本地开发完成后,使用Docker-compose 实现跨环境无差异部署,包含「FastAPI 后端、Vue3 前端、MySQL8.0、Nginx」四大服务,一键启动,同时 Nginx 配置HTTPS、伪静态、Gzip 压缩,满足生产环境和 SEO 要求。
1. 部署配置文件:docker-compose.yml(放在项目根目录)
yaml
version: '3.8'
services:
# MySQL数据库
mysql:
image: mysql:8.0
container_name: geo-mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 你的MySQL密码
MYSQL_DATABASE: geo_seo
MYSQL_CHARSET: utf8mb4
MYSQL_COLLATION: utf8mb4_unicode_ci
volumes:
- ./mysql/data:/var/lib/mysql # 数据持久化
- ./mysql/init:/docker-entrypoint-initdb.d # 初始化脚本
ports:
- "3306:3306"
networks:
- geo-network
# FastAPI后端
backend:
build: ./geo-back # 后端Dockerfile目录
container_name: geo-backend
restart: always
depends_on:
- mysql
environment:
- DB_HOST=mysql # 关联MySQL容器名
volumes:
- ./geo-back:/app
networks:
- geo-network
# Vue3前端(预渲染打包为静态HTML)
frontend:
build: ./geo-front # 前端Dockerfile目录
container_name: geo-frontend
restart: always
volumes:
- ./geo-front/dist:/usr/share/nginx/html # 前端打包目录挂载到Nginx
networks:
- geo-network
# Nginx(反向代理+HTTPS+伪静态+Gzip)
nginx:
image: nginx:1.25
container_name: geo-nginx
restart: always
depends_on:
- backend
- frontend
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf:/etc/nginx/conf.d # Nginx配置文件
- ./nginx/ssl:/etc/nginx/ssl # HTTPS证书
- ./nginx/log:/var/log/nginx # Nginx日志
- ./geo-front/dist:/usr/share/nginx/html # 前端静态文件
networks:
- geo-network
# 自定义网络
networks:
geo-network:
driver: bridge
2. 关键配置补充
-
后端
Dockerfile(geo-back/Dockerfile):dockerfile
FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . . CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"] -
前端
Dockerfile(geo-front/Dockerfile):dockerfile
FROM node:18-slim WORKDIR /app COPY package.json package-lock.json ./ RUN npm install -registry https://registry.npmmirror.com COPY . . RUN npm run build # 打包为静态dist目录 FROM nginx:1.25 COPY --from=0 /app/dist /usr/share/nginx/html -
Nginx 核心配置(
nginx/conf/geo.conf,包含 HTTPS、伪静态、反向代理):nginx
server { listen 80; server_name www.geo-seo.com geo-seo.com; # 80端口重定向到443(HTTPS是SEO必备) return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name www.geo-seo.com geo-seo.com; # HTTPS证书配置 ssl_certificate /etc/nginx/ssl/geo-seo.com.pem; ssl_certificate_key /etc/nginx/ssl/geo-seo.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; # Gzip压缩(提升加载速度) gzip on; gzip_types text/html text/css text/javascript application/json application/javascript; gzip_min_length 1k; # 前端静态文件(伪静态适配) location / { root /usr/share/nginx/html; index index.html; # 适配Vue3路由,避免刷新404 try_files $uri $uri/ /index.html; # 伪静态URL重写(地理词-核心词/ → 实际页面) rewrite ^/([a-z0-9-]+)-([a-z0-9-]+)/$ /detail.html?geo_word=$1&core_word=$2 last; } # 后端API反向代理 location /api/ { proxy_pass http://backend:8000/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 站点地图和robots.txt location /sitemap.xml { root /usr/share/nginx/html; expires 1d; } location /robots.txt { root /usr/share/nginx/html; expires 1d; } # 静态资源缓存 location ~* \.(css|js|jpg|png|gif|ico)$ { root /usr/share/nginx/html; expires 30d; add_header Cache-Control "public, max-age=2592000"; } }
3. 部署步骤(服务器端执行,一键启动)
bash
运行
# 1. 克隆代码到服务器
git clone 你的代码仓库地址 geo-seo
cd geo-seo
# 2. 准备HTTPS证书,放到nginx/ssl目录
# 3. 修改docker-compose.yml中的密码、域名等配置
# 4. 构建并启动所有容器
docker-compose up -d --build
# 5. 查看容器运行状态
docker-compose ps
# 6. 查看日志(如有错误)
docker-compose logs -f
部署成功后,访问https://你的域名即可看到站点,后台管理地址为https://你的域名/admin。
七、运维监控与效果迭代(持续优化排名,核心指标跟踪)
1. 日常运维(保证站点稳定运行)
-
数据备份 :MySQL 定时备份(每天凌晨 2 点),编写 shell 脚本加入服务器 crontab:
bash
运行
#!/bin/bash BACKUP_DIR=/root/geo-seo/backup DATE=$(date +%Y%m%d) docker exec geo-mysql mysqldump -uroot -p你的密码 geo_seo > $BACKUP_DIR/geo_seo_$DATE.sql # 删除7天前的备份 find $BACKUP_DIR -name "geo_seo_*.sql" -mtime +7 -delete -
日志监控:监控 Nginx 访问日志和后端错误日志,及时发现访问异常和程序错误;
-
性能优化 :定期优化 MySQL 索引、清理无用数据,Nginx 开启缓存,内容页面实现静态化(将生成的内容保存为 HTML 文件,而非动态渲染)。
2. SEO 效果监控(核心工具 + 关键指标)
(1)必备监控工具(免费 + 付费结合)
| 工具名称 | 类型 | 核心作用 | 费用 |
|---|---|---|---|
| 百度站长平台 | 搜索引擎官方 | 监控收录、排名、索引量、死链 | 免费 |
| 谷歌搜索控制台 | 搜索引擎官方 | 海外排名监控(如需) | 免费 |
| 5118SEO 工具 | 第三方付费 | 关键词排名、热度、竞争对手分析 | 月付 / 年付 |
| Google Analytics | 流量统计 | 站点流量、用户行为、跳出率 | 免费 |
| 友盟 + | 移动端统计 | 移动端流量、设备适配分析 | 免费 |
(2)核心监控指标(决定优化方向)
- 收录指标:总收录量、日新增收录、未收录页面数(重点优化未收录页面的 TDK 和内容);
- 排名指标:地理长尾词排名(重点关注前 50 名,逐步优化到首页)、核心词排名、品牌词排名;
- 流量指标:独立 IP、页面访问量(PV)、人均访问页数、跳出率(跳出率 > 70% 需优化内容质量);
- 转化指标:咨询量、点击量、下载量(地理长尾词的转化远高于通用词,重点提升)。
3. 持续迭代策略(根据数据调整,排名稳步提升)
- 内容迭代:对排名 50 名以外的关键词,补充更优质的地理化内容,增加本地案例和数据;对排名 10-50 名的关键词,优化页面 TDK 和内链,提升权重;
- 关键词迭代 :通过 5118 工具挖掘更多低竞争高热度的地理长尾词(如 "北京朝阳区装修公司推荐" 比 "北京装修公司推荐" 竞争更低),补充对应内容;
- 外链迭代:根据排名情况,为核心地理长尾词页面增加高权重外链,优先选择本地行业站点;
- 体验迭代:根据用户行为数据(如跳出率、人均访问页数),优化页面内容结构和加载速度,提升用户体验(百度 2026 年核心排名指标:用户体验)。
八、实战注意事项(避坑指南,避免排名清零)
- 合规性 :国内服务器必须备案,否则无法被百度收录;域名避免使用违规字符,站点内容符合国家法律法规,拒绝低俗、虚假内容;
- 拒绝黑帽 SEO:不要使用刷排名、刷流量、垃圾外链、关键词堆砌等黑帽手法,百度算法更新频繁,黑帽会导致站点被降权甚至 K 站;
- LLM 接口限流 :调用 LLM 生成内容时做好接口限流,避免单次调用过多导致超支或接口被封禁;
- 地理信息准确性:内容中的地理信息必须准确(如地址、区域名),错误的地理信息会降低用户体验,影响排名;
- 搜索引擎规则更新 :及时关注百度搜索资源平台 、谷歌搜索博客的规则更新,调整 SEO 策略(如 2026 年百度重点关注「本地真实体验」「内容实用性」);
- 站点稳定性:保证服务器 7*24 小时运行,避免频繁宕机,宕机会导致搜索引擎抓取失败,影响收录和排名。
九、总结
本次 GEO 源码搭建的核心逻辑是 **「技术轻量化 + 内容地理化 + SEO 标准化」**,通过 Python+FastAPI 快速实现地理处理、内容生成、SEO 优化的核心业务,Vue3+Vite 搭建极简前端保证 SEO 适配,Docker-compose 实现一键部署,最终通过「站内 SEO 保证收录 + 站外 SEO 提升排名 + 持续监控迭代稳定排名」,实现地理定向内容站的从零到一搭建和搜索排名优化。