移动环境下的 SEO
· 阅读需 9 分钟
真的有很久很久没来理这个博客,距离上一篇文章的发布日期是两年前。 毕业工作后来了豆瓣,最近对移动环境(主要是浏览器及微信)的 SEO 相关进行了下研究,正好在这里分享一下。
以下,Enjoy。
1. SEO:Search Engine Optimization
产品:搜索引擎优化,促进内容网站信息分享/传播,提高目标转化率,留存率
工程:为各类页面实现统一的信息分享、传播,提高搜索排名(search ranking)
个人觉得:
- 豆瓣是一个内容网站,拥有一些 UGC 优质内容,SEO 间接帮助用户分享。 且分享率越高,也会提高搜索排名。
- M 站的目前面向** 人(User) **的 UX 比较完善,但是仍需要丰富一些细节,让 Search Engine 的 UX 更好,更好地理解 M 站。
2. 前端在 SEO 中的位置
- 帮助产品进行TDK (Title / Description / Keyword)优化
- 添加一些 Social Meta Tag (Facebook / Twitter / G+ / WeChat / Weibo)
- 页面内容优化(HTML5 标签语义化、唯一的 H1 标题、img 设置
alt
属性,不需要爬虫跟踪的链接加nofollow
) - URL 优化 (canonical,标签表示页面的唯一性)
- 在搜索引擎里,只有链接完全一样,才会认为是同一个链接,如果链接带上参数,虽然访问到的内容还是一样,但是在搜索引擎看来确是不同的链接,页面抓取也会出现多次,从而导致多个链接,内容一样。
- 因此 URL 中最好是不要带上查询参数。但为了产品统计数据,总需要
?from=xxx&refer=xxx
等参数,所以使用canonical
标签来确保链接唯一性,避免权重分散、流失。 - 比如
m.douban.com/group/topics[?start=xxx]
均视为同一个页面这里的?start=xxx
是一个分页查询参数,所以为了确保这些页面都能继承 m.douban.group/toics 这个 url 的权重,在head
中增加了canonical
标签
- Meta robots
- Sitemap
3. 具体实现
统一 SNS 抓取
提供一个 mako 函数,统一分享的标题、图片、描述
- Open Graph
- Twitter Card
实现统一的分享接口
可变的图片、标题、描述
微信 (iOS、Android 系统分享菜单、微信内置分享)
- 外部调用分享可能会抓取标题、第一个图片地址(Open Graph)
- 调用内置分享可用第三个链接 (API 跨子域)
微博
参考链接:
https://developers.facebook.com/docs/sharing/opengraph
https://dev.twitter.com/cards/overview
http://github.intra.douban.com/frodo/Talion/blob/master/views/j/wechat/init.py
— From Douban FE Dropbox
实现方案
1. 增加了 seo_meta()
Mako widget
http://github.intra.douban.com/frodo/Talion/blob/master/templates/card/widgets.html#L527
<%def name="seo_meta(title, desc, image=None, url=None, type=None, rating_count=None, rating_val=None, wechat_timeline_title=None,wechat_chat_title=None, wechat_desc=None, wechat_image=None)">
<%
from douban.image.qiniu import qiniu_proxy_url
default_title = '豆瓣'
default_desc = '读书、看电影、涨知识、学穿搭...,加入兴趣小组,获得达人们的高质量生活经验,找到有相同爱好的小伙伴。'
default_image = static('/pics/icon/m_logo_180.png')
default_url = 'http://m.douban.com/'
default_type = 'article'
image = qiniu_proxy_url(image, 300, 300, mode='1') if image else ''
%>
<!-- Schema.org markup for Google+ -->
<meta itemprop="name" content="${ title or default_title }">
<meta itemprop="description" content="${ desc or default_desc }">
<meta itemprop="image" content="${ image or default_image }">
% if rating_count:
<meta itemprop="reviewCount" content="${ rating_count }">
% endif
% if rating_val:
<meta itemprop="ratingValue" content="${ rating_val }">
% endif
<!-- Twitter meta -->
<meta name="twitter:card" content="summary" />
<!-- Open Graph meta -->
<meta property="og:title" content="${ title or default_title }" />
<meta property="og:description" content="${ desc or default_desc }" />
<meta property="og:site_name" content="