我如何用 Python 给 Github 的 README.md 做一个访客统计功能
README.md 是每一个 Github 项目必不可少的文件,用户打开你的项目链接第一眼看到的就是它。如果可以给这个文件添加一个访客统计功能,那么不就知道每天有多少个用户或者一共有多少个用户打开过你的项目了吗?
答案是肯定的,但是因为普通的访客统计系统都需要在 HTML 页面中用 <script>
标签引入一个 js 文件, 而 Github 的 markdown 是不会解析 <script>
的标签的,那么该怎么办呢?看到这里先别急着往下看,开动下脑筋想一想,看看和我实现的方式是不是一样的呢?
下面进入正文,介绍一下我的一个 Python 项目: visitor-badge
这是什么
这是一个统计README页面被打开多少次的 badge 生成服务。
原理
在 README.md 中插入一个 markdown 格式的图片,图片的 src 指向某个服务器地址。
当你每次打开这个页面, 浏览器加载图片时就会向指定的服务器地址发送一个请求。
部署在服务器上的 visitor-badge 项目会处理这个请求,将该页面对应的访问数量加1
之后 visitor-badge 会将最新的访客数量生成出一张 svg 图片返回给浏览器即可。
技术点
badge的生成, 直接使用了google的开源项目 pybadges , 非常简单
利用Flask写了非常简单的web服务, 接受请求, 缓存访问量, 生成svg并返回
遇到的问题
缓存
Github使用了camo作为图片的代理服务器, 当你审查README上的图片元素时, 你会发现所有的图片都不是指向真实的服务器地址, 而是一串https://camo.githubusercontent.com/xxxxxxxxxxxxxxxxxxxxxxxxx/yyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzz.jpg
的网址, 如下:
而camo的服务器会对被代理的图片进行缓存, 使得当第一次刷新页面时, camo会像badge生成服务发起请求, camo记录访问次数为1, 之后再次刷新页面, camo会缓存这个badge图片, 从而无法达到我们想要的效果.
经过一番搜索和研究发现, 在badge生成服务返回的http响应的header中, 需要动一些小手脚:
Cache-Control
设置Cache-Control
的内容为no-cache,max-age=0
, 告诉camo服务器在使用缓存之前进行验证
Expires
这里我手动将资源的过期时间设置成了当前时间减去10分钟
这样的话, 当用户打开README页面之后, camo服务器在返回缓存内容之前, 会像源服务器发起请求, badge生成服务收到请求之后会将访问量加1并生成相应的svg内容同时携带以上2个header信息返回.
而正是由于这两个header的设置, 每次打开页面加载图片时,camo服务器发现缓存的资源在10分钟之前已经过期, 于是就将最新的svg返回给了浏览器.
使用方法
在你的README里面, 添加一个图片:
就会统计当前 README.md 的总访客数量。最终效果如下:
你可以点击 这里 查看效果。
最后留一个思考题,你知道为什么很多邮件客户端都会建议你或者默认地不去加载邮件正文里的图片吗?
版权声明: 本文为 InfoQ 作者【遇见】的原创文章。
原文链接:【http://xie.infoq.cn/article/6bddd6dc3ba79050b3468e9a8】。文章转载请联系作者。
评论