利用周末放假两天时间写了个QQ空间访客记录的爬虫,在这里分享出来;本文将会把要做的步骤都列出来,一步一步的实现这个爬虫程序。
特别注明:
- 本程序仅供学习交流目的
- 请勿用于不可描述的事情
爬取过程中需要获取的关键信息如下:
- 访客列表的URL
- 登录cookie
- 参数g_tk
- 参数skey
需要准备的工具有:
- 浏览器(本文使用的是chrome,配合本文使用的浏览器驱动,所以这里也推荐大家使用chrome浏览器)
- chromedriver——chrome浏览器对应的webdriver驱动,可以根据你自己的chrome浏览器版本到网址中去对应下载,下载完成后将存放的文件夹目录添加到PATH环境变量中即可,这里分享下载链接:http://npm.taobao.org/mirrors/chromedriver/
- 当然还有最基础的一步就是python开发环境了,python、Pycharm IDE等这里就由大家自行配置安装
准备好需要用到的工具后,我们就开始获取上面所列出的关键信息了。
首先是访客列表的URL,这里我们可以使用chrome浏览器进行抓包。首先打开chrome浏览器,打开QQ空间个人中心后,上面会有一排导航栏,我们选择“更多”-“访客”
点击“访客”进去后,我们右击浏览器页面,选择检查,可以看到下方会出现一排工具栏,这时我们选择“Network”项:
刷新页面后,会加载出一些url,我们在filter的输入框中输入“cgi_get_visitor_more“对加载对内容进行过滤,获取以cig_get_visitor开头的url,这其中就包含了g_tk的信息。点击该url,我们就可以看到右边Response加载出的访客信息:
接着,我们回到QQ空间个人中心主页面,同样是在浏览器的Network中查看一个以cgi_get_visitor_simple开头的url,在右侧的“Headers”中找到cookie值:
当准备完这些内容后,我们就可以开始编写python代码了:
首先我们使用webdriver调用chrome浏览器,登录QQ空间获取cookie中的skey,其中qq_number中填写你的QQ号,password为QQ登录密码:
def testLogin():# 抓取空间访客爬虫qq_number = '*******'password = '******'login_url = 'https://i.qq.com/'driver = webdriver.Chrome()driver.get(login_url)# QQ空间登录表单driver.switch_to_frame('login_frame')driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click()time.sleep(1)driver.find_element_by_xpath('//*[@id="u"]').send_keys(qq_number)driver.find_element_by_xpath('//*[@id="p"]').send_keys(password)time.sleep(1)driver.find_element_by_xpath('//*[@id="login_button"]').click()time.sleep(1)cookie_list = driver.get_cookies()cookie_dict = {}for cookie in cookie_list:if 'name' in cookie and 'value' in cookie:cookie_dict[cookie['name']] = cookie['value']return cookie_dict[u'skey']
上面这个函数会获取登录的cookie,并将解析到的skey返回;接着是利用得到的skey计算g_tk,关于计算g_tk的值,网上有很多现成的实现过程,这里参考了其中python的实现:
def get_gtk(skey=u"******")://传入skeyhash = 5381for i in skey:hash += (hash << 5) + ord(i)return hash & 0x7fffffff
这里get_gtk所接收的参数为我们上一个函数中返回的skey,接着,再写一个函数,将获取的skey和g_tk作为参数传入,与上面截图中的url和cookie进行组合,发送请求:
def handler(g_tk, skey):visitorGroup = []# print "执行时间:", str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))url = "https://h5.qzone.qq.com/proxy/domain/g.qzone.qq.com/cgi-bin/friendshow/cgi_get_visitor_more?" \"uin=1020392881&mask=2&g_tk=" + str(g_tk) + "&page=1&fupdate=1"ck = "pgv_pvi=3112891392; RK=7ZTp7714eB; ptcz=f484dc4c707b8bf68892215434d1add2298ba28204850f5e15b838887d1646c9; " \"pgv_pvid=6547699245; __Q_w_s__QZN_TodoMsgCnt=1; QZ_FE_WEBP_SUPPORT=1; cpu_performance_v8=0; " \"__Q_w_s_hat_seed=1; tvfe_boss_uuid=eba8c5a534b14ec1; pgv_si=s8491739136; zzpaneluin=; zzpanelkey=; " \"pgv_info=ssid=s5123913118; uin=o1020392881; skey=" + skey + "; ptisp=ctc; p_uin=o1020392881;" \" pt4_token=" \"zfsDuyYubhixcnuohFoTj*juCnD5tOy208a8z9oeTZg_;" \" p_skey=" \"aHWmXKn-MAjgD-d7mLbHnC09MufXb7MoKpoEYAirUwg_; " \"Loading=Yes; qz_screen=1440x900"cks = {}for c in ck.split(";"):data = c.split("=")cks[data[0].strip(" ")] = data[1]rep = requests.get(url=url, cookies=cks).textrep = rep[rep.find("\"items\":[{"):rep.find("}]")+2]rep = rep.replace("\"items\":[{", "[{")print rep
执行函数后,最终就能打印出我们获取到的访客列表了,最后附上完整代码:
# _*_ encoding:utf-8 _*_
"""
@Time:2019-03-10 12:45:35
@Author:jaris
"""
import requests
import json
import time
from selenium import webdriverdef handler(g_tk, skey):# print "执行时间:", str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))url = "https://h5.qzone.qq.com/proxy/domain/g.qzone.qq.com/cgi-bin/friendshow/cgi_get_visitor_more?" \"uin=1020392881&mask=2&g_tk=" + str(g_tk) + "&page=1&fupdate=1"ck = "pgv_pvi=3112891392; RK=7ZTp7714eB; ptcz=f484dc4c707b8bf68892215434d1add2298ba28204850f5e15b838887d1646c9; " \"pgv_pvid=6547699245; __Q_w_s__QZN_TodoMsgCnt=1; QZ_FE_WEBP_SUPPORT=1; cpu_performance_v8=0; " \"__Q_w_s_hat_seed=1; tvfe_boss_uuid=eba8c5a534b14ec1; pgv_si=s8491739136; zzpaneluin=; zzpanelkey=; " \"pgv_info=ssid=s5123913118; uin=o1020392881; skey=" + skey + "; ptisp=ctc; p_uin=o1020392881;" \" pt4_token=" \"zfsDuyYubhixcnuohFoTj*juCnD5tOy208a8z9oeTZg_;" \" p_skey=" \"aHWmXKn-MAjgD-d7mLbHnC09MufXb7MoKpoEYAirUwg_; " \"Loading=Yes; qz_screen=1440x900"cks = {}for c in ck.split(";"):data = c.split("=")cks[data[0].strip(" ")] = data[1]rep = requests.get(url=url, cookies=cks).textrep = rep[rep.find("\"items\":[{"):rep.find("}]")+2]rep = rep.replace("\"items\":[{", "[{")print repdef get_gtk(skey=u"******"):hash = 5381for i in skey:hash += (hash << 5) + ord(i)return hash & 0x7fffffffdef testLogin():# 抓取空间访客爬虫qq_number = '******'password = '******'login_url = 'https://i.qq.com/'driver = webdriver.Chrome()driver.get(login_url)# QQ空间登录表单driver.switch_to_frame('login_frame')driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click()time.sleep(1)driver.find_element_by_xpath('//*[@id="u"]').send_keys(qq_number)driver.find_element_by_xpath('//*[@id="p"]').send_keys(password)time.sleep(1)driver.find_element_by_xpath('//*[@id="login_button"]').click()time.sleep(1)cookie_list = driver.get_cookies()cookie_dict = {}for cookie in cookie_list:if 'name' in cookie and 'value' in cookie:cookie_dict[cookie['name']] = cookie['value']return cookie_dict[u'skey']def func():skey = testLogin()g_tk = get_gtk(skey)handler(g_tk=g_tk, skey=skey)func()
打印结果如下,其中name为好友的昵称,uin为好友的QQ号: