自毕业后,就再也没有用过QQ,QQ空间里记录的是些并不精彩的青葱岁月,但好歹也是份回忆,近日想着学以致用,用Python把QQ空间相册的所有照片爬取下来,以作备份。
分析QQ空间
登录QQ空间
爬取第一步,分析站点,首先需要知道如何登录QQ空间。最初想法是用requests库配置登录请求,模拟登录,但是不久便放弃了这一思路,请看下图↓
login
根据登录按钮绑定的监听事件可以追踪到该按钮的点击事件如下:
login function
账号加密是必然的,但这一堆堆的代码真心不好解析,有耐心的勇士尽情一试!
在排除这种登录方法后,选择selenium模拟用户登录不失为省时省力的方法,而且我们只是需要通过selenium完成登录,获取到Cookies和后面讲述的g_tk参数后,就可以停用了,所以效率并不太低。
分析空间相册
登录以后,页面会跳转至 [https://user.qzone.qq.com/{QQ_NUMBER}](javascript:;), 这时把鼠标移到导航栏你会发现,所有的导航栏链接都是javascript:; 😳。没错就是这么坑,一切都是暗箱操作。
当然这并不难处理,使用调试工具捕获点击后产生的请求,然后过滤出正确的请求包即可。因为网络包非常多,那么怎么过滤呢,猜想相册数据的API必然会返回个列表list,尝试过滤list然后逐个排除,最后定位到请求包。下面是通过fcg_list过滤后的数据包,列表信息以jsonp格式返回,稍作处理即可当做json格式来读取(后面有讲)。
album list
从Headers和Response可以分别获取到两组重要信息:
request 获取相册列表所需的请求信息,包括请求链接和参数
response 数据包包含的所有相册的信息,是每个相册所含照片对应的请求包参数的数据来源
先看请求包:
# url
https://h5.qzone.qq.com/proxy/domain/photo.qzone.qq.com/fcgi-bin/fcg_list_album_v3
# args
g_tk: 477819917
callback: shine0_Callback
t: 691481346
hostUin: 123456789
uin: 123456789
appid: 4
inCharset: utf-8
outCharset: utf-8
source: qzone
plat: qzone
format: jsonp
notice: 0
filter: 1
handset: 4
pageNumModeSort: 40
pageNumModeClass: 15
needUserInfo: 1
idcNum: 4
callbackFun: shine0
_: 1551788226819
其中hostUin, uin都是QQ号,g_tk是必须的且每次重新登录都会更新(后面有讲如何获取),其它有些参数不是必须的,我尝试后整理出如下请求参数:
query = {
'g_tk': self.g_tk,
'hostUin': self.username,
'uin': self.username,
'appid': 4,
'inCharset': 'utf-8',
'outCharset': 'utf-8',
'source': 'qzone',
'plat': 'qzone',
'format': 'jsonp'
}
接下来看jsonp格式的跨域响应包:
shine0_Callback({
"code":0,
"subcode":0,
"message":"",
"default":0,
"data":
{
"albumListModeSort" : [
{
"allowAccess" : 1,
"anonymity" : 0,
"bitmap" : "10000000",
"classid" : 106,
"comment" : 11,
"createtime" : 1402661881,
"desc" : "",
"handset" : 0,
"id" : "V13LmPKk0JLNRY",
"lastuploadtime" : 1402662103,
"modifytime" : 1408271987,
"name" :