javaqq空间爬⾍_QQ空间动态爬⾍
作者:虚静
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,⾮商业转载请注明出处。
先说明⼏件事:
题⽬的意思是,⽤于获取“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 = 'qzs.qq/qzone/v8/pages/setting/visit_v8.html'
self.headers['Referer'] = referer
print("\tDealing with position\t%d." % position)
res = (url, headers=self.headers)
html =
with open('friends/offset' + str(position) + '.json', 'w') as f:python转java代码
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') dswith("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 = 'user.qzone.qq/' + 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 = (url, headers = self.headers)
con =
with open('mood_result/' + qqnumber + '/' + str(pos), 'w') as f:
f.write(con)
if '''"msglist":null''' in con:
key = False
#
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' % ime())
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秒的⽅式应对的。(所以才那么慢,也不敢上多线程)
最终获取到的所有好友的说说⽂件,还需要⾃⼰去提取所需要的信息。本程序只获取源数据,不处理数据。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。