使用python+selenium爬取qq空间好友动态

分析过程如下:

要想用selenium登陆qq空间,必须点击账号密码登陆按钮然后再填写账号密码登陆。

1.PNG

点击账号密码按钮后跳转到如下页面:

2.PNG

以上过程实现代码:

# 这是你的chromedriver的对应版本文件

chrome_driver = r'E:\迅雷下载\chromedriver_win32\chromedriver.exe'

driver = webdriver.Chrome(executable_path=chrome_driver)

driver.get('https://qzone.qq.com/')

# driver.

# 切换网页框架

driver.switch_to.frame(driver.find_element_by_id('login_frame'))

# print(driver.page_source)

# 切换到账户密码输入界面

driver.find_element_by_id('switcher_plogin').click()

接下来就是输入账号、密码,点击登陆。

代码如下:

# 输入账号

driver.find_element_by_id('u').clear()

driver.find_element_by_id('u').send_keys('****') # 此处填写账号

# 输入密码

driver.find_element_by_id('p').clear()

driver.find_element_by_id('p').send_keys('****') # 此处填写密码

# 登陆账号

driver.find_element_by_id('login_button').click()

# 等待三秒让浏览器加载完

time.sleep(3)

登陆过后就进入了qq空间,但有可能不是好友动态页面,这是就需要用selenium来模拟点击跳转到好友动态页面:

3.PNG

代码如下:

driver.find_element_by_xpath('//*[@id="tab_menu_friend"]/div[3]').click()

# 休息3秒等待页面加载完

time.sleep(3)

这时我们就进入了qq空间好友动态页面,但是我发现好友动态是页面局部刷新加载出来的,所以要去查找动态加载文件。经过查找,我发现动态加载信息存放在feeds_3_html....文件下。

4.PNG

使用代码直接获取这个页面会报错,因为这个页面不仅需要登陆,而且他请求地址中的g_tk查询字符串还是通过加密构造的,其中有两个字段非常关键,一个是begintime,还有一个是加密得到的g_tk。

5.PNG

begintime这个字段是你的动态请求中第一条动态的上一条动态的发布时间的时间戳。

g_tk这个字段是在jQuery中加密的字段。

jQuery中加密代码如下:

getACSRFToken:function(url) {

url = QZFL.util.URI(url);

var skey;

if (url) {

if (url.host && url.host.indexOf("qzone.qq.com") > 0) {

try {

skey = QZONE.FP._t.QZFL.cookie.get("p_skey");

} catch (err) {

skey = QZFL.cookie.get("p_skey");

}

} else {

if (url.host && url.host.indexOf("qq.com") > 0) {

skey = QZFL.cookie.get("skey");

}

}

}

if (!skey) {

skey = QZFL.cookie.get("p_skey") || (QZFL.cookie.get("skey") || (QZFL.cookie.get("rv2") || ""));

}

var hash = 5381;

for (var i = 0, len = skey.length;i < len;++i) {

hash += (hash << 5) + skey.charCodeAt(i);

}

return hash & 2147483647;

为了获取g_tk,首先是要获取登陆过后的cookies。

代码如下:

# 获取cookie为字典形式

cookie_dict = {i['name']: i['value'] for i in driver.get_cookies()}

# 把cookie转化为字符串形式:name1=value1; name2=value2;

cookie_str = ''

for key, value in cookie_dict.items():

cookie_str += key + '=' + value + '; '

用python实现的加密代码如下:

# -*- coding: UTF-8 -*-

import re

class GetGTK(object):

def __init__(self, cookiestr):

self.cookieStr = cookiestr

self.p_skey = None

self.skey = None

self.rv2 = None

def getNewGTK(self):

skey = self.p_skey or self.skey or self.rv2

hash = 5381

for i in range(0, len(skey)):

hash += (hash << 5) + ord(skey[i])

return hash & 2147483647

def handler(self):

if re.search(r'p_skey=(?P[^;]*)', self.cookieStr):

self.p_skey = re.search(r'p_skey=(?P[^;]*)', self.cookieStr).group('p_skey')

else:

self.p_skey = None

if re.search(r'skey=(?P[^;]*)', self.cookieStr):

self.skey = re.search(r'skey=(?P[^;]*)', self.cookieStr).group('skey')

else:

self.skey = None

if re.search(r'rv2=(?P[^;]*)', self.cookieStr):

self.rv2 = re.search(r'rv2=(?P[^;]*)', self.cookieStr).group('rv2')

else:

self.rv2 = None

def run(self):

self.handler()

return self.getNewGTK()

if __name__ == '__main__':

cookiestr = "cookies" # 这是你的登陆后的cookie

getGTK = GetGTK(cookiestr)

g_tk = getGTK.run()

print(g_tk)

获取begintime。

代码如下:

basetime = driver.find_elements_by_xpath('//*[@id="feed_friend_list"]//li[@class="f-single f-s-s"]').pop().get_attribute(

'id').split('_')[4]

获取begintime可以直接在id里面获取,id中包含了发布动态的时间戳。

6.PNG

有了begintime和g_tk后,我们就可以组装url了,然后就可以用requests加上cookies信息请求url,就可以获取到空间好友动态了。

# 构造url

url = 'https://user.qzone.qq.com/proxy/domain/ic2.qzone.qq.com/cgi-bin/feeds/feeds3_html_more?uin=1392853401&begintime={}&g_tk={}'.format(begintime, g_tk)

# 发起请求

res = requests.get(base_url, cookies=cookie_dict)

print(res.content.decode())

获取的结果如下

7

.PNG

再在浏览器中请求这个url,得到结果如下

8.PNG

发现用代码抓取的空间动态信息正确,接下来就是用一般的数据处理方法来清洗数据(xpath,re,或者beautifulsoup),要注意的是构造下一个请求的begintime要用到上一个请求结果中最后一条消息的发布时间的时间戳。例如下图中最后一个动态的发布时间戳为1563797364。

9.PNG

下一个Ajax请求的begintime就是1563797364。

10

这样就可以构造连续的请求来获取空间好友动态消息。

最后附上源代码:

from selenium import webdriver

import time

import requests

# 导入密钥构造类

from get_g_tk import GetGTK

from lxml import etree

import demjson

import pymongo

myclient = pymongo.MongoClient('mongodb://localhost:27017/')

mydb = myclient['QQDongTaiInfo']

mycollection = mydb['QQDongTaiInfo']

class GetQQDongTaiInfo(object):

chrome_driver = r'E:\迅雷下载\chromedriver_win32\chromedriver.exe'

def __init__(self, username, password):

self.driver = webdriver.Chrome(executable_path=GetQQDongTaiInfo.chrome_driver)

self.cookies = {}

self.username = username

self.password = password

self.base_url = 'https://user.qzone.qq.com/proxy/domain/ic2.qzone.qq.com/cgi-bin/feeds/feeds3_html_more?uin={}&begintime={}&g_tk={}'

# g_tk为jquery中加密的字段,用登陆的cookie信息进行加密

self.g_tk = None

self.begintime = None

def login_qq_zone(self):

self.driver.get('https://qzone.qq.com/')

# 切换网页框架

self.driver.switch_to.frame(self.driver.find_element_by_id('login_frame'))

# 切换到账户密码输入界面

self.driver.find_element_by_id('switcher_plogin').click()

# 输入账号

self.driver.find_element_by_id('u').clear()

self.driver.find_element_by_id('u').send_keys(self.username)

# 输入密码

self.driver.find_element_by_id('p').clear()

self.driver.find_element_by_id('p').send_keys(self.password)

# 登陆账号

self.driver.find_element_by_id('login_button').click()

time.sleep(3)

self.driver.find_element_by_xpath('//*[@id="tab_menu_friend"]/div[3]').click()

time.sleep(3)

self.cookies = {i['name']: i['value'] for i in self.driver.get_cookies()}

def get_static_html_info(self):

page_source = self.driver.page_source

self.begintime = self.driver.find_elements_by_xpath(

'//*[@id="feed_friend_list"]//li[@class="f-single f-s-s"]').pop().get_attribute(

'id').split('_')[4]

html = etree.HTML(page_source)

# 获取静态网页中的动态消息

dongtai_contents = html.xpath('//li[@class="f-single f-s-s"]')

# print(dongtai_content)

single_info = dict()

for temp in dongtai_contents:

# 动态内容

single_info['content'] = temp.xpath(".//div[starts-with(@id,'feed_')]/div[@class='f-info']/text()")

# print(single_info['content'])

# 动态发布者名称

single_info['publisher_name'] = temp.xpath(".//a[contains(@class,'f-name')]/text()")

# 动态发布时间戳

single_info['push_date'] = temp.xpath(".//*[starts-with(@id,'hex_')]/i/@data-abstime")

# 动态浏览次数

single_info['view_count'] = temp.xpath(".//a[contains(@class,'state qz_feed_plugin')]/text()")

# 动态评论

single_info['comments-content'] = temp.xpath(".//div[@class='comments-content']//text()")

# 点赞次数

# print(temp.xpath(".//span[@class='f-like-cnt']/text()"))

single_info['like'] = temp.xpath(".//span[@class='f-like-cnt']/text()")

# print(single_info)

self.save_to_mongdb(single_info)

self.cookies = {i['name']: i['value'] for i in self.driver.get_cookies()}

cookie_str = ''

for key, value in self.cookies.items():

cookie_str += key + '=' + value + '; '

self.g_tk = GetGTK(cookie_str).run()

def get_dynamic_info(self):

requests_url = self.base_url.format(self.username, self.begintime, self.g_tk)

print(requests_url)

res = requests.get(requests_url, cookies=self.cookies).content.decode()

res_dict = demjson.decode(res[10: -3])

# 如果没有请求到正确数据,再次发出请求

try:

res_datas = res_dict['data']['data']

except KeyError:

self.get_dynamic_info()

return None

res_datas = [temp for temp in res_datas if isinstance(temp, dict)]

# res_datas_len = len(res_datas)

for temp in res_datas:

single_info = dict()

html = etree.HTML(temp['html'])

# 动态内容

single_info['content'] = html.xpath("//div[@class='f-info']/text()")

# print(single_info['content'])

# 动态发布者名称

single_info['publisher_name'] = temp['nickname']

# 动态发布时间戳

single_info['push_date'] = temp['abstime']

# 动态浏览次数

single_info['view_count'] = html.xpath("//a[@class='state qz_feed_plugin']/text()")

# 动态评论

single_info['comments-content'] = html.xpath("//div[@class='comments-content']//text()")

# 点赞次数

# print(temp.xpath(".//span[@class='f-like-cnt']/text()"))

single_info['like'] = html.xpath(".//span[@class='f-like-cnt']/text()")

# print(single_info)

self.save_to_mongdb(single_info)

if temp == res_datas[-1]:

self.begintime = single_info['push_date']

self.get_dynamic_info()

def save_to_mongdb(self, single_info):

if mycollection.find({'push_date': single_info['push_date']}).count() == 0:

mycollection.insert_one(single_info.copy())

print('插入成功')

else:

print('插入失败')

def run(self):

self.login_qq_zone()

self.get_static_html_info()

self.get_dynamic_info()

if __name__ == "__main__":

username = '***' # qq账号

password = '***' # qq密码

Demo = GetQQDongTaiInfo(username, password)

Demo.run()

结果保存在了mongdb数据库中,结果如下:

12.PNG

以上就是用selenium+python获取qq空间好友动态的全部流程,谢谢浏览。

python爬取加密qq空间_使用python+selenium爬取qq空间好友动态相关推荐

  1. python实现rsa加密解密代码_使用python实现rsa算法代码

    RSA算法是一种非对称加密算法,是现在广泛使用的公钥加密算法,主要应用是加密信息和数字签名. 维基百科给出的RSA算法简介如下: 假设Alice想要通过一个不可靠的媒体接收Bob的一条私人讯息.她可以 ...

  2. Python爬取网站用户手机号_用Python爬虫爬取学校网妹子QQ号,100行代码撩妹,用技术脱单...

    前言: 其实这个项目没什么难度,稍微懂一点爬虫的人或者是已经就业的程序员都可以用自己学的编程语言写出来,但是正是这也原因,也间接证明现在网络很多安全问题的存在,简单的说就是这个网站的程序员偷懒,让用户 ...

  3. python访问陌生人qq空间_使用Python+Selenium模拟登录QQ空间

    使用Python+Selenium模拟登录QQ空间 爬QQ空间之类的页面时大多需要进行登录,研究QQ登录规则的话,得分析大量Javascript的加密解密,这绝对能掉好几斤头发.而现在有了seleni ...

  4. python多线程爬取多个网址_【Python爬虫】多线程爬取斗图网站(皮皮虾,我们上车)...

    原标题:[Python爬虫]多线程爬取斗图网站(皮皮虾,我们上车) 斗图我不怕 没有斗图库的程序猿是无助,每次在群里斗图都以惨败而告终,为了能让自己在斗图界立于不败之地,特意去网上爬取了斗图包.在这里 ...

  5. python 爬取直播弹幕视频_调用斗鱼API爬取直播间弹幕信息(用户昵称及弹幕内容)...

    调用斗鱼API爬取直播间弹幕信息(用户昵称及弹幕内容) 查看<斗鱼弹幕服务器第三方接入协议v1.4.1>,了解斗鱼API的使用方法,即如何连接斗鱼弹幕服务器.维持连接及获取弹幕信息 Pyt ...

  6. Python爬取网站用户手机号_利用python爬取慕课网站上面课程

    1.抓取网站情况介绍 抓取网站:http://www.imooc.com/course/list 抓取内容:要抓取的内容是全部的课程名称,课程简介,课程URL ,课程图片URL,课程人数(由于动态渲染 ...

  7. 用python输出所有的玫瑰花数_用Python爬取WordPress官网所有插件

    转自丘壑博客,转载注明出处 前言 只要是用WordPress的人或多或少都会装几个插件,可以用来丰富扩展WordPress的各种功能.围绕WordPress平台的插件和主题已经建立了一个独特的经济生态 ...

  8. python3爬取微博评论教程_用python 爬取微博评论,怎么打开微博评论下的查看更多|...

    怎样用python爬新浪微博大V所有数据 先上结论,通过公开的api如爬到某大v的所有数据,需足以下两个条件: 1.在你的爬虫开始运行时,该大v的所有微博发布量没有超过回溯查询的上限,新浪是2000, ...

  9. python 循环定时器 timer显示数据_【Python】多线程、定时循环爬取优信二手车信息...

    爬虫 爬取优信二手车:循环遍历每页,获取相应的有价值字段信息,这里不详细阐释了. 多线程 Python中,使用concurrent.futures模块下的ThreadPoolExecutor类来实现线 ...

最新文章

  1. java表单提交包含文件_如何同时提交表单中的文件和文本
  2. win7中PowerShell终端打开时自动进入python virtualenv的虚拟环境以及一键切换python版本
  3. oracle之数据处理之视图练习
  4. 华三防火墙h3cf100配置双宽带_H3C新一代F100系列防火墙评测报告
  5. 【李宏毅机器学习】Convolutiona Neural Network 卷积神经网络(p17) 学习笔记
  6. vos3000下载java_VOS3000 安装
  7. [转贴]深山红叶使用图文教程
  8. 【信息融合】基于BP神经网络和DS 证据理论实现不确定性信息融合问题附matlab代码
  9. WinDriver_资料
  10. [AngularJS面面观] 20. 依赖注入 --- instance注入器以及provider注入器
  11. control c linux命令,linux中Control+C是什么指令?使用什么命令可以给一个进程发出一个这样的指令?...
  12. Excel中换行的问题
  13. python提取图片中的文字自动填表_python写一个自动识别图片提取文字
  14. java调用百望税控NISEC_SKSC.dll发送xml报文
  15. 计算机科学与技术职业规划社会环境分析,大学生职业生涯规划书计算机科学与技术...
  16. 【考】现代传感器技术作业一至四 复习用
  17. mysql报错1357_mysql8 参考手册--错误代码1343-1367
  18. 好用的图片翻译器有哪些?这3个工具你们不能不知道
  19. python群聊聊天室程序_Python聊天室程序---基础
  20. r语言找不到cochrane函数_网状meta必备技能之6-利用R中的meta包实现meta分析

热门文章

  1. 软件测试整理一:测试基础知识以及开发、测试模型、按照开发阶段进行测试
  2. 充分的准备新任学校领导
  3. python教程80--两个Excel表做对比,找出表的值有哪些差异
  4. 性价比高的蓝牙耳机有哪些?蓝牙耳机排行榜10强
  5. 字节数组转换为字符串会造成数据损失的一些解释
  6. 点击眼睛图标更改密码显示格式
  7. [ERDAS] 裁剪 拼接 融合 修改指定像素的值
  8. 详述 @Service 和 @Resource 注解的区别
  9. 2022年秋中科大-数字图像分析-期末考试试卷回忆版及汇总--USTC
  10. git登录账号密码错误remote: Incorrect username or password (access token)