Python网络爬虫5-爬取QQ空间相册
Python⽹络爬⾍5-爬取QQ空间相册
⾃毕业后,就再也没有⽤过QQ,QQ空间⾥记录的是些并不精彩的青葱岁⽉,但好⽍也是份回忆,近⽇想着学以致⽤,⽤Python把QQ空间相册的所有照⽚爬取下来,以作备份。
分析QQ空间
登录QQ空间
爬取第⼀步,分析站点,⾸先需要知道如何登录QQ空间。最初想法是⽤requests库配置登录请求,模拟登录,但是不久便放弃了这⼀思路,请看下图↓
根据登录按钮绑定的监听事件可以追踪到该按钮的点击事件如下:
账号加密是必然的,但这⼀堆堆的代码真⼼不好解析,有耐⼼的勇⼠尽情⼀试!
在排除这种登录⽅法后,选择selenium模拟⽤户登录不失为省时省⼒的⽅法,⽽且我们只是需要通过selenium完成登录,获取到Cookies和后⾯讲述的g_tk参数后,就可以停⽤了,所以效率并不太低。
分析空间相册
当然这并不难处理,使⽤调试⼯具捕获点击后产⽣的请求,然后过滤出正确的请求包即可。因为⽹络包⾮常多,那么怎么过滤呢,猜想相册数据的API必然会返回个列表list,尝试过滤list然后逐个排除,最后定位到请求包。下⾯是通过fcg_list过滤后的数据包,列表信息以jsonp格式返回,稍作处理即可当做json格式来读取(后⾯有讲)。
从Headers和Response可以分别获取到两组重要信息:
1. request 获取相册列表所需的请求信息,包括请求链接和参数
2. response 数据包包含的所有相册的信息,是每个相册所含照⽚对应的请求包参数的数据来源
先看请求包:
# url
h5.qzone.qq/proxy/domain/photo.qzone.qq/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" : "毕业季",
"order" : 0,
"pre" : "http:\/\/b171.photo.store.qq\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfGuwSk58K2rQY!\/a\/dIY29GUbJgAA",        "priv" : 1,
"pypriv" : 1,
"total" : 4,
"viewtype" : 0
},
复制代码
shine0_Callback是请求包的callbackFun参数决定的,如果没这个参数,响应包会以_Callback作为默认名,当然这都不重要。所有相册信息以json格式存⼊albumListModeSort中,上⾯仅截取了⼀个相册的信息。
相册信息中,name代表相册名称,id作为唯⼀标识可⽤于请求该相册内的照⽚信息,⽽pre仅仅是⼀个预览缩略图的链接,⽆关紧要。
分析单个相册
与获取相册信息类似,进⼊某⼀相册,使⽤cgi_list过滤数据包,到该相册的照⽚信息
同样的道理,根据数据包可以获取照⽚列表信息的请求包和响应信息,先看请求:
# url
h5.qzone.qq/proxy/domain/photo.qzone.qq/fcgi-bin/cgi_list_photo
# args
g_tk: 477819917
callback: shine0_Callback
哪个牌子的羽绒服好t: 952444063
mode: 0
idcNum: 4
hostUin: 123456789
topicId: V13LmPKk0JLNRY
noTopic: 0
uin: 123456789
pageStart: 0
pageNum: 30
skipCmtCount: 0
singleurl: 1
batchId:
notice: 0
appid: 4
inCharset: utf-8
outCharset: utf-8
source: qzone
plat: qzone
outstyle: json
format: jsonp
json_esc: 1
question:
answer:
callbackFun: shine0
_: 1551790719497
复制代码
其中有⼏个关键参数:
1. g_tk - 与相册列表参数⼀致
2. topicId - 与相册列表参数中的id⼀致
3. pageStart - 本次请求照⽚的起始编号
4. pageNum - 本次请求的照⽚数量
为了⼀次性获取所有照⽚,可以将pageStart设为0,pageNum设为所有相册所含照⽚的最⼤值。
4岁孩子的教育同样可以对上⾯的参数进⾏简化,在相册列表请求参数的基础上添加topicId,pageStart和pageNum三个参数即可。下⾯来看返回的照⽚列表信息:
shine0_Callback({
"code":0,
"subcode":0,
"message":"",
"default":0,
"data":
{
"limit" : 0,
"photoList" : [
{
"batchId" : "1402662093402000",
"browser" : 0,
"cameratype" : " ",
"cameratype" : " ",
"cp_flag" : false,
"cp_x" : 455,
"cp_y" : 388,
"desc" : "",
"exif" : {
"exposureCompensation" : "",
"exposureMode" : "",
"exposureProgram" : "",
"exposureTime" : "",
"flash" : "",
"fnumber" : "",
"focalLength" : "",
"iso" : "",
"lensModel" : "",
"make" : "",
"meteringMode" : "",
"model" : "",
"originalTime" : ""
},
"forum" : 0,
"frameno" : 0,
"height" : 621,
"id" : 0,
"is_video" : false,
"is_weixin_mode" : 0,
"ismultiup" : 0,
"lloc" : "NDN0sggyKs3smlOg6eYghjb0ZRsmAAA!",
"modifytime" : 1402661792,
"name" : "QQ图⽚20140612104616",
"origin" : 0,
"origin_upload" : 0,
"origin_url" : "",
"owner" : "123456789",
"ownername" : "123456789",
"photocubage" : 91602,
"phototype" : 1,
"picmark_flag" : 0,
"picrefer" : 1,
"platformId" : 0,
"platformSubId" : 0,
"poiName" : "",
"pre" : "http:\/\/b171.photo.store.qq\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfSk58K2rQY!\/a\/dIY29GUbJgAA&bo=pANtAgAAAA          "raw" : "http:\/\/r.photo.store.qq\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km
91gIWfSk58K2rQY!\/r\/dIY29GUbJgAA",
"raw_upload" : 1,
"rawshoottime" : 0,
"shoottime" : 0,
"shorturl" : "",
"sloc" : "NDN0sggyKs3smlOg6eYghjb0ZRsmAAA!",
"tag" : "",
"uploadtime" : "2014-06-13 20:21:33",
"url" : "http:\/\/b171.photo.store.qq\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfSk58K2rQY!\/b\/dIY29GUbJgAA&bo=pANtAgAAAA          "width" : 932,
"yurl" : 0
},
过路费什么时候免费
// ...
]
"t" : "952444063",
"topic" : {
"bitmap" : "10000000",
"browser" : 0,
"classid" : 106,
"comment" : 1,
"cover_id" : "NDN0sggyKs3smlOg6eYghjb0ZRsmAAA!",两弹一星之父到底是谁
"createtime" : 1402661881,
"desc" : "",
"desc" : "",
"handset" : 0,
"id" : "V13LmPKk0JLNRY",
"is_share_album" : 0,
"lastuploadtime" : 1402662103,
"modifytime" : 1408271987,
"name" : "毕业季",
"ownerName" : "707922098",
"ownerUin" : "707922098",
"pre" : "http:\/\/b171.photo.store.qq\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km9
1gIWfGuwSk58K2rQY!\/a\/dIY29GUbJgAA",      "priv" : 1,
"pypriv" : 1,
"share_album_owner" : 0,
"total" : 4,
"url" : "http:\/\/b171.photo.store.qq\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfGuwSk58K2rQY!\/b\/dIY29GUbJgAA",      "viewtype" : 0
中秋客户祝福短信},
"totalInAlbum" : 4,
"totalInPage" : 4
}
复制代码
返回的照⽚信息都存于photoList, 上⾯同样只截取了⼀张照⽚的信息,后⾯⼀部分返回的是当前相册的⼀些基本信息。totalInAlbum,totalInPage存储了当前相册总共包含的照⽚数及本次返回的照⽚数。⽽我们需要下载的图⽚链接则是url!
OK, 到此,所有请求和响应数据都分析清楚了,接下来便是coding的时候了。
确定爬取⽅案
1. 创建qqzone类,初始化⽤户信息
2. 使⽤Selenium模拟登录
3. 获取Cookies和g_tk
4. 使⽤requests获取相册列表信息
5. 遍历相册,获取照⽚列表信息并下载照⽚
创建qqzone类
class qqzone(object):
"""QQ空间相册爬⾍"""
def __init__(self, user):
self.username = user['username']
self.password = user['password']
复制代码
模拟登录

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