facebook数据采集——利用BigPipe技术和xpath解析数据

本文介绍了Facebook的前端加速技术BigPipe,解释了为何在解析Facebook数据时选用XPath而非BeautifulSoup,并提供了BigPipe技术的工作原理和PageLet的概念。同时,通过实例展示了XPath在处理HTML数据中的应用,帮助进行有效的数据采集。
摘要由CSDN通过智能技术生成

前言

上一篇博文是我写的第一篇博文,存在了各种各样的小bug:换行不规范、出现莫名其妙的html标签等等。在以后会慢慢改正。

这篇文章主要是介绍两个技术,一个是网页前端加速BigPipe技术,另一个是html数据解析需要用到的xpath技术。

为什么我在数据解析的时候没有用比较成熟的BeautifulSoup?因为facebook的网页源码过于庞大,或多或少存在和标准不一样的地方(这不影响浏览器的解析),使得BeautifulSoup无法正确加载分析,所以采取了xpath的方法。如果大家有什么好方法能够使BS加载facebook的html请留言和我探讨哈!


BigPipe技术


为什么要介绍BigPipe?

因为最开始的时候根本找不到我们需要的数据在哪里,第一眼看见源码我是基本是一脸懵逼的,来感受一下,下图是登陆facebook后主页的掩码。看一看sublime右边那个整体预览,一大片黄色代码(很大一部分都是json数据)。



可以看到下载了很多JS脚本,还有很多注释掉的html(灰色部分):



不过没关系,我们直接搜索想找的信息就好了,比如我关注了扎克伯格,搜索Mark Zuckerberg,发现大部分的Mark Zuckerberg都出现在注释里。我们都知道,注释里的代码是不会被执行的。但是通过观察可以发现,注释里的代码,的确出现在了网页中,并被执行了。所以可以这样理解:注释里的代码相当于输入数据,通过JS脚本的解析,最终呈现在了浏览器上。经过观察,我们需要的信息都在注释中,可是注释这么多,到底去哪里找?或者说,如何从这么多代码里找到我们想要的信息,并且能够避开无关信息(广告,推广之类的)?这个时候就需要用到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,将数据放置其中。加载示意图如下:


这时候我们就可以根据PageLet基本信息(还记得那一大串json数据吗?)就可以确定哪条数据是广告,哪条是推广,而哪条是我们需要采集的数据。这一下就避开了一大推会造成混淆的数据。

代码编写

啰嗦了这么多,终于把问题交代清楚了。。。

首先,我们要看一看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)):
        # 
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值