前言
上一篇博文是我写的第一篇博文,存在了各种各样的小bug:换行不规范、出现莫名其妙的html标签等等。在以后会慢慢改正。
这篇文章主要是介绍两个技术,一个是网页前端加速BigPipe技术,另一个是html数据解析需要用到的xpath技术。
为什么我在数据解析的时候没有用比较成熟的BeautifulSoup?因为facebook的网页源码过于庞大,或多或少存在和标准不一样的地方(这不影响浏览器的解析),使得BeautifulSoup无法正确加载分析,所以采取了xpath的方法。如果大家有什么好方法能够使BS加载facebook的html请留言和我探讨哈!
BigPipe技术
为什么要介绍BigPipe?
BigPipe简介
BigPipe技术是facebook在2010年前提出的一种前端加速技术,效果极其明显,facebook个人主页的加载时间从原来的5s缩短到了2.5s。这是一个很了不起的成就,因为有研究显示,当用户打开一个网页的时间超过3s还收不到任何反应,那么差评就少不了了。2,5s刚好小于3s,但是在实际使用中,用户的真实体验远远小于2.5s,为什么呢?请继续往后看。
在传统的页面加载方法中,整个web页面在服务器端组合好后再通过网络传输至用户端,最后由浏览器解析数据并展示给用户。而BigPipe技术借鉴了CPU的流水线技术,将网页切割成不同的模块,如下图,每个黑框代表了一个模块,在BigPipe中,模块的学名叫做PageLet。
在服务器端,网页的生成不再以页面为单位,而是以PageLet为单位。每生成好一个PageLet,就将该模块发送至用户端。多个PageLet并行发送,大大提高了页面的整体加载速度。一图读懂传统方法与BigPipe技术的不同:
每个PageLet都包含了数据——完整Dom树,以及必要的基本信息,例如编号、放置位置。JavaScript解析脚本会读取PageLet的基本信息,根据其中的分类信息,选择相应的container,将数据放置其中。加载示意图如下:
代码编写
啰嗦了这么多,终于把问题交代清楚了。。。
首先,我们要看一看html,找一找它们的规律。
前面十几行代码,主要是下载css样式表和js脚本。接着十几行是初始化BigPipe。然后就进入了正轨。
来看看PageLet基本信息:
这么长一段其实只有一句代码,主要的意思是执行了bigPipe.onPageletArrive()这个函数,从名字就能看出来这个函数是干嘛的,至于后面的一大堆,就是PageLet的基本信息了。在里面能找到一些有用的东西:
"display_dependency":["topnews_main_stream_408239535924329"] 这条数据表示显示在哪个模块上吧。topnews这个关键词告诉我们这是置顶新闻,不是我们需要采集的信息。
"content":{"substream_0":{"container_id":"u_0_x"}指示出来container的id号。
后面还有jsmods,requires之类的参数,没啥意义。
定位到用户发布的消息,发现一个模式:"display_dependency":["substream_X"],其中X(大)是数字,或者"display_dependency":["substream_X_xxxxxxxxx"],其中x(小)是数字或字母。经过观察,符合这个模式的PageLet都是我们需要采集的数据——用户发布的“朋友圈”。这个结论不一定靠谱,因为没有任何理论依据,也没有任何文档可供查看。但是在我所遇见的情况中,这种方法完美的避开了所有广告和推广。
PageLet的数据信息,就在这条代码的上面。不要忘记,DOM树代码是被注释起来的,注释内可能存在换行,这是因为有人发“朋友圈”时,发了好几段话,造成了空格的产生。我们只需要一直往上找,找到注释的起始位置即可。实现起来也比较简单:def get_newdom_from_html(file_path):
# 把html存在了文件中,便于调试
file = open(file_path)
html = file.readlines()
data = []
for i in range(len(html)):
#