作者:虚静

链接:https://zhuanlan.zhihu.com/p/24656161

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

先说明几件事:

  • 题目的意思是,用于获取“QQ空间动态”的爬虫,而不是”针对QQ空间“的”动态爬虫“
  • 这里的QQ空间动态,特指“说说”
  • 程序是使用cookie登录的。所以如果是想知道如何使用爬虫根据QQ号和密码来实现登录的朋友可以把页面关了
  • 本程序用python3实现,具体版本为python3.5,唯一需要用到的第三方库是requests
  • 程序代码获取方式在最后面

----------------------------------------

程序主要由三部分构成,它们分别对应着本爬虫的三个步骤。

1. 获取所有QQ好友信息

间接获取。先把QQ空间的访问权限设置为仅QQ好友可访问

点保存后,上方会出现“当前权限下,XXX好友可以访问你的空间”的提示,如上图。此时打开F12,切换到JavaScript监测窗口。点击上图中画下划线的那几个字,就可以发现浏览器发送了一个GET请求,在Firebug中看到是这样的:

查看它的response,会发现里面就是由自己好友的名字和QQ号码组成的近似于JSON格式的内容。爬虫程序中的get_my_friends.py就是用于获取它的内容的,其主要代码如下:

    def get_friends(self):
key = True
position = 0
while key:
url = self.base_url + '&offset=' + str(position)
referer = 'http://qzs.qq.com/qzone/v8/pages/setting/visit_v8.html'
self.headers['Referer'] = referer print("\tDealing with position\t%d." % position)
res = requests.get(url, headers=self.headers)
html = res.text
with open('friends/offset' + str(position) + '.json', 'w') as f:
f.write(html) # 检查是否已经全部都获取完,如果是的话
# uinlist对应的是一个空列表
with open('friends/offset' + str(position) + '.json') as f2:
con = f2.read()
if '''"uinlist":[]''' in con:
print("Get friends Finish")
break position += 50

2. 获取所有好友的QQ号码

这一步其实只是文本处理,或者说是字符串处理而已。把上一步中保存好的文件进行处理,从中提取好友的QQ号码和名称,将其保存在一个文件中(其名为qqnumber.inc)。由于其内容本身近于字典形式,所以稍加处理,将其转成字典,再进行处理。处理程序为爬虫程序中的get_qq_number.py,主要代码如下:

def exact_qq_number(self):
friendsFiles = [x for x in os.listdir('friends') if x.endswith("json")] qqnumber_item = []
i = 0
for each_file in friendsFiles:
with open('friends/' + each_file) as f:
source = f.read()
con_dict = source[75:-4].replace('\n', '')
con_json = json.loads(con_dict)
friends_list = con_json['uinlist'] # Get each item from friends list, each item is a dict
for item in friends_list:
i = i + 1
qqnumber_item.append(item)
else:
with open('qqnumber.inc', 'w') as qqfile:
qqfile.write(str(qqnumber_item))

3. 分别获取每个好友的空间动态(说说)

获取好友的说说,方法类似于第1步。先打开F12,保持在默认的All选项卡下就行。再打开好友的空间,点开他们的说说主页,此时可以在请求列表中找到一个URL中包含emotion_cgi_msglist的请求,根据名字就可以猜到,它就是我们要的信息了。然后我们可以模拟这个请求,获取返回的内容并保存。爬虫程序中的get_moods.py就用于此。

此程序文件中包含两个类:Get_moods_start()、Get_moods()。后者实现发送HTTP请求并获取返回内容、保存内容,前者用于把QQ号传到后者的方法中进行处理、控制循环、处理异常。Get_moods()功能实现的主要方法代码如下:

def get_moods(self, qqnumber):
'''Use cookie and header to get moods file and save it to result folder with QQnumber name''' referer = 'http://user.qzone.qq.com/' + qqnumber
self.headers['Referer'] = referer # Create a folder with qq number to save it's result file
util.check_path('mood_result/' + qqnumber) # Get the goal url, except the position argument.
url_base = util.parse_moods_url(qqnumber)
pos = 0
key = True while key:
print("\tDealing with position:\t%d" % pos)
url = url_base + "&pos=%d" % pos
res = self.session.get(url, headers = self.headers)
con = res.text
with open('mood_result/' + qqnumber + '/' + str(pos), 'w') as f:
f.write(con) if '''"msglist":null''' in con:
key = False # Cannot access...
if '''"msgnum":0''' in con:
with open('crawler_log.log', 'a') as log_file:
log_file.write("%s Cannot access..\n" % qqnumber)
key = False # Cookie expried
if '''"subcode":-4001''' in con:
with open('crawler_log.log', 'a') as log_file:
log_file.write('Cookie Expried! Time is %s\n' % time.ctime())
sys.exit() pos += 20
time.sleep(5)

程序运行的结果会保存在名为mood_result的文件夹中,其中包含以各好友QQ号码为名的文件夹,他们的说说信息文件都保存在对应的文件夹中。

-----------------------------------------

其它说明

程序还有两个文件,util.py和main.py,后者是程序运行的入口,前者则包含了一些通用功能,例如获取cookie、生成发送HTTP请求时要用到的g_tk值、构造URL。此处讲一下g_tk值。

在前面第1步和第3步中,发送的HTTP请求的URL参数里面,都包含有g_tk值,这个值是通过cookie中的p_skey参数的值生成的。可以在登录QQ空间时通过F12查看JS文件,找到它的对应算法。它位于名为qzfl_v8_2.1.57的js文件中。由于该文件内容过大,近6千行,在firebug中直接看response还找不到,不过可以通过在response中搜索得到,或者将单独在浏览器中打开,就可以得到它的全部内容了。找到这个g_tk的计算方法:

不要被这里的hash误导,在python里面hash()是一个内置方法,但在JS中,在此处,它只是个变量名而已。在本爬虫程序里面是这样实现的:

def get_g_tk():
''' make g_tk value''' pskey_start = cookie.find('p_skey=')
pskey_end = cookie.find(';', pskey_start)
p_skey = cookie[pskey_start+7: pskey_end] h = 5381 for s in p_skey:
h += (h << 5) + ord(s) return h & 2147483647

主要是通过位移和并运算,得到一个唯一值。

最后

如第3步中贴出来的代码后面部分写的,如果好友的空间不对自己开放,那么是无法获取到他的说说的,发送请求后有返回,但主要内容是空的。

如果cookie过期了,程序会记录日志并自动退出。我的程序运行了15个小时,请求了494个好友的说说文件,发送1万1千多个请求(每个请求得到一个文件,我的结果文件夹中就有这么多个文件),cookie没有过期,也没有被空间反爬。哦,对了,为了防止反爬虫,本程序是使用每请求一个文件就暂停5秒的方式应对的。(所以才那么慢,也不敢上多线程)

最终获取到的所有好友的说说文件,还需要自己去提取所需要的信息。本程序只获取源数据,不处理数据。

Github代码链接:QQzone_crawler

QQ空间动态爬虫的更多相关文章

  1. QQ空间说说爬虫

    QQ空间说说爬虫 闲来无事,写了一个QQ空间的爬虫,主要是爬取以前的说说,然后生成词云. 这次采用的主要模块是selenium,这是一个模拟浏览器的模块,一开始我不想用这个模块写的,但是后面分析的时候 ...

  2. QQ空间动态内容,好友信息,点赞爬虫脚本

    一.安装基础的软件包: 1.准备好火狐浏览器,并下载geckodriver,将geckodriver加入到环境变量:下载geckodriver的地址:https://pan.baidu.com/s/1 ...

  3. 仿QQ空间动态界面分享

    先看看效果: 用极少的代码实现了 动态详情 及 二级评论 的 数据获取与处理 和 UI显示与交互,并且高解耦.高复用.高灵活. 动态列表界面MomentListFragment支持 下拉刷新与上拉加载 ...

  4. qq空间爬取

    QQ_spider github传送门 QQ空间spider总结 花了将近3天吧,完成了低配版qq空间的爬虫,终于能上线刚一波了,还是蛮期待的. 流程很简单,模拟登录 ==>采集==>保存 ...

  5. 长姿势 教你在qq空间上显示iPhone6尾巴

    下午刚午休完的时候,广州很多童鞋都感受到了震感,半青也感受到了,不仅如此,我还感受到了更大震感,那就是翻一下QQ空间动态,竟然看到有一位好友的尾巴竟然显示为“iPhone6”,顿时觉得该好友逼格太高了 ...

  6. QQ空间爬虫最新分享,一天 400 万条数据(附代码地址)

    http://mp.weixin.qq.com/s?__biz=MzAxMjUyNDQ5OA==&mid=2653552228&idx=1&sn=e476bf23556406c ...

  7. Python爬虫实战:使用Selenium抓取QQ空间好友说说

    前面我们接触到的,都是使用requests+BeautifulSoup组合对静态网页进行请求和数据解析,若是JS生成的内容,也介绍了通过寻找API借口来获取数据. 但是有的时候,网页数据由JS生成,A ...

  8. QQ空间爬虫--获取好友信息

    QQ空间网页版:https://user.qzone.qq.com/ 登陆后,进入设置,有一个权限设置,设置“谁能看我的空间”为好友可见,然后构造爬虫. (1)获取Cookie 两种方式: 第一种:通 ...

  9. Python 爬虫监控女神的QQ空间新的说说,实现邮箱发送

    主要实现的功能就是:监控女神的 QQ空间,一旦女神发布新的说说,你的邮箱马上就会收到说说内容,是不是想了解一下 先看看代码运行效果图: PS:只有你有一台云服务器你就可以把程序24h运行起来 直接上代 ...

随机推荐

  1. 为你的Web程序加个启动画面

    .Net开发者一定熟悉下面这个画面: 这就是宇宙第一IDE Visual Studio的启动画面,学名叫Splash Screen(或者Splash Window).同样,Javar们一定对Eclip ...

  2. ABP框架 - OData 集成

    文档目录 本节内容: 简介 安装 安装Nuget包 设置模块依赖 配置你的实体 创建控制器 示例 获取实体列表 请求 响应 获取单个实体 请求 响应 获取单个实体及导航属性 请求 响应 查询 请求 响 ...

  3. 2017-1-5 天气雨 React 学习笔记

    官方example 中basic-click-counter <script type="text/babel"> var Counter = React.create ...

  4. mybatis_个人总结

    在使用mybatis框架开发数据访问层的过程中,我在这段时间遇到很多细节问题困住我,在这里我来分享一下我遇到的坑,希望能帮到大家. 一.mybatis动态代理方式开发的规范: 1.注意在mybatis ...

  5. Linux上如何查看物理CPU个数,核数,线程数

    首先,看看什么是超线程概念 超线程技术就是利用特殊的硬件指令,把两个逻辑内核模拟成两个物理芯片,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高的CPU的 ...

  6. 【Machine Learning】Python开发工具:Anaconda+Sublime

    Python开发工具:Anaconda+Sublime 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现 ...

  7. CSS 3学习——文本效果和@font-face

    文本效果 关于文本效果,这里仅仅记录得到大多数浏览器支持的几个属性,分别是: text-overflow text-shadow word-break word-wrap text-overflow ...

  8. Struts2入门(六)——国际化

    一.前言 1.1.国际化简介 国际化是指应用程序在运行的时候,根据客户端请求来自的国家地区.语言的不同而显示不同的界面(简单说就是根据你的地区显示相关地区的语言,如果你现在在英国,那么显示的语言就是英 ...

  9. IIS启动失败,启动Windows Process Activation Service时,出现错误13:数据无效 ;HTTP 错误 401.2 - Unauthorized 由于身份验证头无效,您无权查看此页

    因为修改过管理员账号的密码后重启服务器导致IIS无法启动,出现已下异常 1.解决:"启动Windows Process Activation Service时,出现错误13:数据无效&quo ...

  10. TCP/IP之Nagle算法与40ms延迟

    Nagle算法是针对网络上存在的微小分组可能会在广域网上造成拥塞而设计的.该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组确认到达之前不能发送其他的小分组.同时,TCP收集这 ...