使用HeadlessChrome做单页应用SEO

news/2024/7/19 11:19:44 标签: javascript, 爬虫, 前端框架

随着react、vue、angular等前端框架的流行越来越多的web应用变成了单页应用,它们的特点是异步拉取数据在浏览器中渲染出HTML。使用这些框架极大的提升web用户体验和开发效率的同时缺带来一个新问题,那就是这样的网页无法被搜索引擎收录。虽然这些web框架支持服务端渲染,但这可能又会增加开发成本。

有没有一个可用于任何单页应用的SEO解决方案,让我们不用对代码做改变保持原有的开发效率?chrome-render可以帮我们做到这点,它通过控制HeadlessChrome渲染出最终的HTML返回给爬虫来实现。

HeadlessChrome介绍

前不久chrome团队宣布chrome支持headless模式,HeadlessChrome支持chrome所具有的所有功能只不过因为不显示界面而更快资源占用更小。相比于之前的phantomjs(作者因为HeadlessChrome的推出而宣布停止维护)chrome的优势在于它又一个很强的爹(google)会一直维护它优化它,并且chrome在用户量、体验、速度、稳定性都是第一的,所以我认为HeadlessChrome会渐渐替代之前所有的HeadlessBrowser方案。

如何操控HeadlessChrome

既然HeadlessChrome是以无界面模式运行的,那要怎么控制它和它交互?
chrome提供了远程控制接口,目前可以通过chrome-remote-interface来用js代码向chrome发送命令进行交互。在启动chrome的时候要开启远程控制接口,然后通过 chrome-remote-interface 连接到chrome后再通过协议控制chrome。具体操作见文档:

  • 以headless模式和远程控制模式启动chrome

  • 连接到远程chrome控制它

  • 控制chrome时支持哪些操作具体怎么用

chrome-render原理与实践

原理

chrome-render先会通过chrome-runner以headless模式启动和守护你操作上的chrome,再通过chrome-remote-interface操控chrome去访问需要被SEO的网页让chrome运行这个网页,等到包含数据的HTML被渲染出来时读取当前网页DOM转换成字符串后返回。

怎么知道你的网页什么时候已经渲染出包含数据的HTML了可以返回了呢?为了提升chrome-render效率,默认会在domContentEventFired时返回。对于复杂的场景还可以通过开启chrome-render的useReady选项,等到网页里调用了window.chromeRenderReady()时返回。

只渲染出了HTML还不够我们还需要检测出来着搜索引擎爬虫的访问,如果请求来着爬虫就返回chrome-render渲染后的HTML否则返回正常的单页应用所需HTML。

综上,整体架构如下:
koa-seo arch

实践

只需以下几行简单代码就可让chrome渲染出HTML:

const ChromeRender = require('chrome-render');
ChromeRender.new().then(async(chromeRender)=>{
    const htmlString = await chromeRender.render({
       url: 'http://qq.com',
    });
});    

chrome-render只是做了渲染出HTML的工作,要实现SEO还需要和web服务器集成。为了方便大家使用我做了一个koa中间件koa-seo,要集成到你现有的项目很简单,如下:

const seoMiddleware = require('koa-seo');
const app = new Koa();
app.use(seoMiddleware());

只需像这样接入一个中间件你的单页应用就被SEO了。

应用场景扩展

chrome-render除了用于通用SEO解决方案其实可以用于通用服务端渲染,因为目的都是渲染出最终的HTML再返回。针对通用服务端渲染我也做了一个koa中间件koa-chrome-render。使用chrome-render做服务端渲染的

优势在于:

  • 通用,适用于所有单页应用

  • 对原有代码几乎无改动,最多再合适的地方加个window.chromeRenderReady(),保持原有开发效率

缺点在于:

  • 和react、vue等只带的服务端渲染相比性能低(经我测试大约 200ms vs 60ms)

  • chrome-render渲染时占用资源高,一次渲染大约占用25Mb内存,当请求量大时服务器可能扛不住。但是可以通过缓存渲染结果优化。

总结

大家可能会说这个很像prerender.io,没错思路是一样的,chrome-render的优势在于:

  • chrome-render开源可自己部署,prerender要收费是商业产品

  • prerender基于已经停止维护的phantomjs

本文中所提到的相关项目都是开源的并且有详细的使用文档,它们的文档链接如下:

  • chrome-render

  • chrome-runner

  • koa-seo

  • koa-chrome-render

喜欢的给个star,希望大家和我一起来改进它们让它们更强大。

阅读原文


http://www.niftyadmin.cn/n/842493.html

相关文章

给Linux装图形化界面

在工作中遇到这种情况,安装confluence服务的时候需要调用图形化桌面,但是原来装系统的时候是最小化装的,所以这里就麻烦了 给装图形化吧 在我们安装Linux系统时,刚开始的时候可能没有安装图形界面的需要,但在使用过程中…

Spring Boot 中的 WebSocket 是什么,原理,如何使用

Spring Boot 中的 WebSocket 是什么,原理,如何使用 前言 WebSocket 是一种支持双向通信的网络协议,可以让客户端和服务器之间实现实时通信。Spring Boot 提供了对 WebSocket 的支持,可以方便地在应用程序中实现实时通信功能。本…

redis安装+客户端

redis安装客户端1.安装redi2.安装redis客户端1.安装redi 1)资源下载地址 Redis安装包:https://github.com/MicrosoftArchive/redis/releases 2) 下载,解压安装包到相应的文件夹,任一盘符都可以。 接下来对文件夹中的部…

Oracle自定义数据类型 1

原文 oracle 自定义类型 type / create type 一 Oracle中的类型 类型有很多种,主要可以分为以下几类: 1、字符串类型。如:char、nchar、varchar2、nvarchar2。2、数值类型。如:int、number(p,s)、integer、smallint。3、日期类型。…

python scheduler

PYTHON SCHEDULERscheduler简介参考连接安装基本概念介绍项目实例interval 触发器scheduler简介 scheduler提供了基于日期、固定时间间隔以及crontab 类型的任务; 我们可以在主程序的运行过程中快速增加新作业或删除旧作业; 如果把作业存储在数据库中&a…

f-string‘{},{},{}‘

f-string{},{},{}💖1.引号知识点梳理1.普通字符串"" 和 没啥区别2.当字符串本身有引号是,最外层和本身的引号要不同3.三引号,可以跨越多行,可以区分和4.比如οnclickFUNB("2")2.f-string{},{},{}1.学习链接2.…

【模拟练习】[一]

1684: 金币 时间限制: 1 Sec 内存限制: 128 MB提交: 143 解决: 97[提交][状态][讨论版]题目描述 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天) ,每天收到两枚…

pyinstaller pd.read_csv 报错:Initializing from file failed

pyinstaller 报错:Initializing from file failed第一种方法:第二种方法:建议使用:当你用pandas读取文件报这种错误时,一般是因为你的文件名中带有中文,例如:res pd.read_csv(‘我的文件.csv’) 这种情况就…