基于Chrome无头浏览器的SEO解决方案

单页应用SEO优化一直以来是一个比较头疼的问题,尤其是在项目上线后进行SEO优化这可能会造成项目代码大量更改或者更换技术框架。我们想得到一个解决方案尽量避免修改已有代码来解决SEO优化问题。

一 方案介绍

当前解决方案可以理解成爬虫流量欺骗,将来自爬虫的访问流量转发到一个代理服务中,代理服务负责将已有的单页应用渲染成静态页面并返回给爬虫进行爬取。拓扑结构图如下图所示:

拓扑图.jpg

1.1 方案优点:

  1. 可以理解为对已有代码零更改,只需在对应页面增加TDK设置即可;
  2. 对客户访问没有影响,负载层进行分流客户流量永远访问不到代理服务;
  3. 对代理服务器进行开发可以在不更难改原有业务服务源码的的基础上增加TDK相关配置;

1.2 方案缺点:

  1. 由于是预渲染--->展示过程所以页面延时会增加,需要进行相应的缓存优化避免网站被打低分影响SEO推荐;
  2. Nginx层分辨爬虫流量规则需要根据爬虫技术更新进行调整,如果使用ip过滤方式怎需要记录相关搜索引擎的服务器ip列表;

二 如何实现

当前解决方案最为核心的技术问题就是如何在服务端将单页应用按需求渲染出来,并保证渲染出来的页面内容与浏览器中查看的内容是相同的。是否有一种方案可以模拟浏览器的能力将页面内容在本地渲染?

Chrome无头浏览器可以做到,在不需要打开任何窗体的情况下将web页面渲染到本地简单理解就是用chrome打开页面然后点击文件网页另存为到x x.html其实就是这么个过程。

2.1 命令方式使用

以mac系统为例首先本地安装chrome浏览器,命令行执行

alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"

配置环境变量让chrmoe命令生效然后执行命令

chrome --headless --disable-gpu --dump-dom https://www.baidu.com

可以看到网页信息打印到控制台,关于Chrome无头浏览器其他能力可进入https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md 查看

2.2 以编程方式使用

Puppeteer是Chrome小组开发的Node库。它提供了高级API来控制无头(或完整)Chrome。它与其他自动测试库(如Phantom和NightmareJS)相似。

Puppeteer可用于轻松获取屏幕截图,创建PDF,浏览页面以及获取有关这些页面的信息。如果您想快速自动化浏览器测试,则建议使用该库。它隐藏了DevTools协议的复杂性,并处理了诸如启动Chrome的调试实例之类的多余任务。

2.2.1 尝试使用

确保本地nodejs环境是正常可使用的,运行如下命令:

mkdir puppeteerdemo
cd puppeteerdemo
npm init
npm install puppeteer --save
touch index.js

然后在index.js中写入如下内容

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://www.baidu.com');
    await page.screenshot({ path: 'example.png' });
    console.info(await page.content())
    await browser.close();
})();

保存文件运行

node index.js

执行成功后会在项目目录下看到一张名为baidu.png的图片图片内容为百度首页,并且控制台打印出html页面内容其他api可以在Puppeteer网站查看。

2.2.2 实现代理服务

首先我们先创建一个React框架的单页应用程序,这里使用umijs脚手架创建执行如下命令

yarn create umi demo-web

按照提示进行相关信息选择和填写,然后进入到demo-web目录下执行

yarn run start

执行完成请求http://localhost:8000可以看到umi基础项目页面

image-20221009163528793.png

右键点击页面选择显示网页源码可以看到下图:

image-20221009192107028.png

可以看出当前页面是一个典型的单页应用源码,首页只有一个script引用

打开2.2.1章节创建的 puppeteerdemo项目将index.js内容做如下更改

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('http://localhost:8000');
    await page.evaluate(() => { });
    console.log(await page.content())
    await browser.close();
})();

执行

node index.js

会看到如下截图,可以看出已经得到了渲染后的静态页面。

image-20221009173001247.png
2.2.3 制作http协议接口输出静态页面

2.2.2章节已经可以输出页面静态内容到控制台上了现在只需要将代码翻译成一个可以对外提供服务器的后端服务项目即可,项目地址https://dreamsleep.coding.net/public/seo/seo-proxy/git/files

2.2.4 分辨流量来源

Nginx增加配置

upstream seo_proxy_server {
  server localhost:3000;
}
 
#在  location / 中添加
 
if ($http_user_agent ~* "Baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|bingbot|Sosospider|Sogou Pic Spider|Googlebot|360Spider") {
     proxy_pass  http://seo_proxy_server;
}

以上配置是根据http_user_agent中的值进行流量分辨,如果需要根据IP或其他特征值进行分辨可根据情况增加配置。

写在最后

本文所阐述的解决方案属于一个补救方案,在项目开始时分析是否存在SEO需求,然后采用SSR框架进行前端项目架构搭建这样会在后续的开发中遇到SEO相关需求处理起来便会更加从容一些。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容