单页面应用seo的困难在哪里?做seo必须了解
优采云 发布时间: 2021-06-19 05:23单页面应用seo的困难在哪里?做seo必须了解
公司使用angularJs(以下都是参考ng1)框架做互联网应用,之前没接触过seo。突然,运营端来了一个任务:给@k14做搜索引擎优化@,需要研发支持,搜索了一下,发现单页应用做SEO比较费力,国内相关实践资料分享比较少,有点尴尬,前后费了不少功夫终于完成了,记录下来,做个总结,希望能帮到大家,做类似工作的朋友,少走弯路。建议需要seo的网站技术选型尽量不要使用单页框架之类的作为angular react,如果你在做完之后和我网站一样发现自己需要seo,那就去看看吧。如果你已经有了更好的方案,欢迎分享。
在单个页面上应用 SEO 的难点在哪里?
做seo,必须了解爬虫工作的基本原理。搜索引擎可以找到一个网页,因为它已将其编入索引。在此之前,爬虫需要抓取网站页面并将其存储为快照。快照的内容是页面的静态内容。一般来说,右键查看网页源代码的内容,可以看到爬虫可以抓取的内容。爬虫得到一个url后,抓取它的页面信息,在页面中找到a标签,获取下一个url重定向地址,继续爬取下一个页面。 seo的工作目的是增加搜索引擎对网站的索引,提高页面排名。网站上tdk的优化、网站url的优化、外链的增加等传统seo工作都是为了达到这些目的。这有一个共同的前提,就是网页内容可以被搜索引擎抓取,单页seo应用的难度就卡在这里了。
如果你的应用是为angularjs等单页面应用开发的,右击查看源码会发现网站没有动态数据。不幸的是,搜索引擎抓取的页面也是如此。这主要是由于两个原因:
路由、模板和ajax请求
Angular 的单页解决方案是使用路由机制来配合模板引擎。通过自定义模板,一个应用只有一个主页面,通过路由在不同状态之间切换,嵌套对应的模板引擎。模板中的动态数据是通过ajax请求从后端获取的。从路由跳转到渲染完整页面的过程,除了主页面的基本静态数据,都是由js完成的。
爬虫不执行js
了解第一篇文章后,看到这里就很明显了。不幸的是,爬虫不执行 js 脚本。这不难理解。搜索引擎每天都有大量的页面需要抓取。执行js会大大降低效率;此外,执行js脚本的搜索引擎也存在巨大的安全隐患。
搜索引擎得到一个url后,就得到了,就结束了。它只获取主页面中的几行静态信息。 Angular框架维护了后端发起的路由、主页、前端ajax请求等js完成的工作,搜索引擎不会处理。
网址优化
下面放爬虫方案,先说url优化。用过 angularjs 的人都知道,ng 的 url 依赖 # 来标识一个状态。 #类似符号的网址对seo非常不友好,根据同事的回复(我没验证过),搜索引擎不会访问#后面内容的网址。总之,URL优化是SEO单页应用中无法回避的工作,我们的目的就是将URL优化成类似目录结构的URL,这是爬虫最喜欢的形式。
如何去掉ng frame url中的#,google和百度都能搜到很多资料。如:
简单来说,去掉#,只需要在路由中配置$locationProvider.html5Mode(true)即可;开启html5模式后,url会自动去掉#和.html后缀,达到最优。但是此时有一个问题:f5刷新会因为404找不到页面。 原因是f5会提交url给后端获取资源,而html5模式下优化的url没有这样的后台资源。直接访问这个链接,如果找不到主页面,自然会得到404。上面链接中给出的解决方案是nodejs后端解决方案。我们的解决方案是使用springMVC后端,但是原理是类似的:后端不识别这个链接,所以我们把错误的连接重定向到了原来的连接#,是对后端的正常访问,而#中的# url 将在浏览器端再次被 html5 模式移除。
重定向工作可以在后端springMVC过滤器中解决,也可以在容器中解决。我们的框架在后端使用 nginx 进行负载平衡。我把重定向放在nginx.conf中,对各个路由状态的URL做了对应的原创URL重定向,问题解决了。无论你如何刷新或访问,页面都是一个简单舒适的目录结构url。
两个可抓取的解决方案
url优化后,继续往下看。说白了,我们要做的是针对单页应用的可爬取解决方案,即如何让搜索引擎获取全内容的页面信息。我调查了一些现有的解决方案,想法是相似的。搜索引擎不执行js,我们无法改变,所以只能像照顾宝宝一样自己执行js,获取模板和动态数据,渲染一个完全静态的页面,交给爬虫。我在git上研究了两个方案并分享了。如果你有更好的方案,欢迎分享。
Project一、johnhuang-cn/
,这是一个java后端解决方案。主要分为服务器端过滤器和本地爬虫两部分。服务器端过滤器有两个作用:一是获取url,二是识别搜索引擎请求并重定向到本地快照;本地爬虫是将页面渲染为本地快照。工作流程大致如下:
在 web.xml 中配置过滤器。当您第一次访问网站 时,过滤器会抓取 url 并将其提供给本地爬虫。这个爬虫是一个具有动态数据抓取能力的爬虫。主要使用selenium+phantomjs框架。你可以自己google这两个框架。其中phantomjs是一个webkit核心。之所以能捕获动态数据,是因为它可以获取dom元素执行事件和相关js。获取完整的页面信息后,会将表单对应的URL:#/about静态存储在一个名为.也就是说,我们需要等待本地爬虫将每个URL渲染成本地快照,然后当搜索引擎爬虫来访问时,过滤器会将请求重定向到对应的快照页面。过滤器如何识别爬虫?它是通过 http 标头中的 userAgent 实现的。每个搜索引擎都有自己的 userAgent,可以在过滤器中配置。
优点:这个程序有几个优点。 1、部署比较简单,对于java应用,配置比较方便简单。 2、搜索引擎访问效率更快。由于快照已保存,搜索引擎抓取后会直接返回静态页面。
缺点:这个程序也有几个缺点。 1、本地爬虫爬的很慢。对于我们拥有海量动态数据的信息模块来说,保存快照是一项耗时的任务。 2、Real-time,框架通过配置本地抓取频率来更新快照,也就是说搜索引擎抓取页面的实时性受到更新频率的限制。 3、stability,不知道这些问题是否还存在。可能因为当时框架还不是很成熟,我试用的时候本地爬虫的激活不够稳定。另外phantomjs进程退出失败,导致后台启动。大量phantomjs内存耗尽。 4、分布式部署问题,我们用nginx负载均衡做了一个后端集群。搜索引擎来了之后,按照规则分发到不同的后端,导致使用这个框架要部署在各个后端,造成了一系列的不便和问题。
由于上述弊端,我最终放弃了这个计划。
Project二、prerender.io
这个方案是我在研究过程中发现的一个比较成熟的方案,完美的解决了我的需求。*敏*感*词*如下,可以参考:
prerender.io 也分为客户端和服务端预渲染服务两部分。客户端的工作是识别搜索引擎请求并重定向它们(类似于计划一)。除了userAgent,它还使用escaped_fragment 进行搜索引擎识别。 ,这是谷歌的一套可爬取的解决方案,详见:谷歌的ajax爬取协议。如果您的网站主要针对国内浏览器进行优化,则基本可以忽略。使用 userAgent 就足够了。预渲染服务器负责接收客户端重定向的请求,接收到请求后,再次向Web后端发出请求。同理,prerender后端集成phantomjs执行js获取动态数据。预渲染后端获取完整页面数据后,将完整页面返回给搜索引擎。
Prerender的客户端现在有多种技术实现,基本可以满足各种技术方案。服务器有两种选择:1、使用官方的prerender.io云服务2、搭建自己的prerender后端服务。官网介绍推荐使用云服务,但是官网要求FQ,使用别人服务的稳定性总是让人堪忧。我选择自己部署预渲染服务。其实就是一个单独运行的nodejs进程,用forever命令运行后还是很稳定的。
优点:1、实时性高。通过以上分析,我们可以了解到预渲染服务实时获取搜索引擎请求进行页面渲染。这意味着如果部署后站点没有重大变化,则不会有后续工作。每次搜索引擎返回与用户访问相同的内容时,都是最新的数据。 2、分布式部署,预渲染服务是一个与web应用完全分离的进程,无论后端有多少集群,都不会影响部署。 3、Stability,框架比较成熟,缓存机制和黑白名单体验非常好。预渲染服务在用forever daemon运行后基本没有遇到不稳定的问题。
缺点:1、搜索引擎爬取效率,页面是实时渲染的,搜索引擎爬取自然会比较慢,不过我们不太在意这个。
对比两种方案,我自然选择了预渲染方案。我在部署实践中遇到了一系列问题。如果需要,我会写预渲染部署实践文章。
总结
总的来说,单页应用能够爬取的最大问题是搜索引擎不执行js。解决方案无非就是我们做动态数据渲染,喂给爬虫。确认了这些之后,自己完成这样一个框架并不难。