有一天我突然发现自己空间的说说竟然已经达到1833条,于是萌生了爬一下看看的想法(其实就是想学下python爬虫)。我找了一些博客,方法不少,但是有些并不适用。所以我把真正能用的方法记录下来,并且爬取了我自己的全部说说,亲测可用。下面我介绍下爬虫的写法。

  • 用到的库——

selenium,requests,json,sqlite3,re,time,random

其中,selenium是用于模拟QQ空间登录的库,即一些动态页面的操作;requests爬虫常用库,不赘述;sqlite3用来存爬取的数据,python3之后的版本自带;re正则表达式,用来提取一些匹配字段。

  • QQ空间说说板块分析——

我们先打开自己的QQ空间,点击说说,会跳转到https://user.qzone.qq.com/your qq number/infocenter这样一个页面,查看网页源码,搜索说说的具体内容,我们是无法找到的。这说明说说的内容、点赞数、评论等都不是静态页面的一部分,而是通过Ajax等手段访问后台加载得到的,因此,我们需要模拟浏览页面的过程,即需要用selenium。

仔细查看浏览器控制台中,筛选出XHR部分的响应正文。可以得到两个重要的url,如下:

  1. https://h5.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6
  2. https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/user/qz_opcnt2

第1条链接的响应正文包含了丰富的信息,格式是json。分析json格式,可以发现具体的内容都在msglist数组中,正常情况下一般是返回20条说说,所以数组长度是20。其中,有非常多可用的信息,如conlist属性下包括说说的具体内容(con),说说发表的时间戳(created_time),以及位置信息(lbs),都可以用来做一些相关的分析和可视化。这里提取content,cmtnum,tid和created_time,分别存储了说说具体内容,评论数,tid后面会用到,是一条说说的标识,以及说说发表时的时间戳。先将这四部分存入sqlite数据库中。

第2条链接是获取一些数值指标的接口,例如点赞数、评论数等等,这里为了获取点赞数,用第1个接口就无法获取,因此需要从数据库获取tid,根据它作为参数之一从第2条说说获取点赞数,再更新数据库,完成爬取任务。

以上就是爬虫的整体思路。

  • 代码部分——

先创建一个sqlite数据库,用于存储爬去的数据,会在.py文件目录中生成一个.db文件数据库,代码如下:

#coding = 'utf-8'import sqlite3def create(dbname,sql):conn = sqlite3.connect(dbname)c = conn.cursor()c.execute(sql)conn.commit()conn.close()def main():dbname = 'mineqqzone.db'tablename = 'qqzoneinfo'createsql = '''create table qqzoneinfo(id integer primary key autoincrement,#idcomment text,#说说内容cmtnum int,#评论数likenum int,#点赞数tid text,#参数createtime long)#时间戳'''create(dbname,createsql)main()

首先要模拟登陆,具体代码在start_login()函数中,需要注意的是,获取g_tk这个参数的方法是对cookie中的p_skey进行加密得到,具体代码在get_g_tk()函数中,这段代码网上找找都找得到。

用selenium模拟浏览器需要下载例如phantomJS、Chromedriver这类的驱动,网上大部分是Chromedriver,但是我试了下配置似乎十分麻烦,所以选择phantomJS(无界面的浏览器),下载的链接在这http://phantomjs.org/download.html,可以下载对应版本。使用时只需在webdriver.PhantomJS()中把phantomjs.exe的路径赋给executable_path即可。虽然selenium现在的版本好像已经把phantomjs剔除了,但是似乎不影响使用。

qzonetoken参数可以从登陆后的html页面中提取,用正则表达式。

#coding = 'utf-8'from selenium import webdriver
import requests
import json
from lxml import etree
from bs4 import BeautifulSoup
import sqlite3
import re
import time
import randomdef get_g_tk(cookie):#获取g_tk参数,由cookie中的p_skey加密得到hashes = 5381for letter in cookie['p_skey']:hashes += (hashes << 5) + ord(letter)  # ord()是用来返回字符的ascii码return hashes & 0x7fffffffdef start_login():#模拟登录QQ空间driver = webdriver.PhantomJS(executable_path = "E:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe")url = "https://qzone.qq.com/"driver.get(url)driver.switch_to.frame('login_frame')driver.find_element_by_id('switcher_plogin').click()driver.find_element_by_id('u').clear()driver.find_element_by_id('u').send_keys('你的QQ号')  driver.find_element_by_id('p').clear()driver.find_element_by_id('p').send_keys('你的QQ密码')  driver.find_element_by_id('login_button').click()time.sleep(3)#等待加载完毕html = driver.page_sourceg_qzonetoken = re.search('window\.g_qzonetoken = \(function\(\)\{ try\{return (.*?);\} catch\(e\)',html)qzonetoken = str(g_qzonetoken[0]).split('\"')[1]#获取参数之一cookie_list = driver.get_cookies()#获取cookiecookie_dict = {}for cookie in cookie_list:cookie_dict[cookie['name']]=cookie['value']g_tk = get_g_tk(cookie_dict)return cookie_dict,g_tk,qzonetoken

我们开始爬取评论、说说、评论数、时间戳,代码如下:

def sqlopr(conn,cur,item):#存入数据库cur.execute("insert into qqzoneinfo (comment,cmtnum,tid,createtime) values (?,?,?,?)",(item['content'],int(item['cmtnum']),item['tid'],item['created_time']))conn.commit()def spidercmt():#爬取评论cookie,g_tk,qzonetoken = start_login()headers={'User-Agent':'打开浏览器控制台查看,复制过来即可'}conn = sqlite3.connect('mineqqzone.db')cur = conn.cursor()sessions = requests.session()count = int(你的说说总数/20) + 1for i in range(count):pos = 当前爬取的说说数量减1 + i*20#因为有可能中途会爬取出错,你可以改变pos继续爬,哈哈哈param = {'uin': '你的QQ号','ftype': '0','sort': '0','pos': pos,'num': '20',#爬取的说说条数,网页上默认是20条'replynum': '100','g_tk': [g_tk, g_tk],#用在这'callback': '_preloadCallback','code_version': '1','format': 'jsonp','need_private_comment': '1','qzonetoken': qzonetoken#用在这}respond = sessions.get('https://h5.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6',params=param,headers=headers,cookies=cookie)r = re.sub("_preloadCallback","",respond.text)test = r[1:-2]Data = json.loads(test)if not re.search('lbs',test):print('说说下载完成')else:for j in range(len(Data['msglist'])):sqlopr(conn,cur,Data['msglist'][j])time.sleep(2)#可以改时间print("suc"+str(i))

以下是爬取点赞数的代码:

def spiderlikenum():cookie,g_tk,qzonetoken = start_login()conn = sqlite3.connect('mineqqzone.db')cur = conn.cursor()sessions = requests.session()count = len(cur.execute('select * from qqzoneinfo where likenum is Null').fetchall())url = 'http://user.qzone.qq.com/你的QQ号/mood/'while count != 0:ress = cur.execute('select * from qqzoneinfo where likenum is Null').fetchall()count = len(ress)-1idc = ress[0][0]tid = ress[0][4]_stp = int(round(time.time() * 1000)) #时间戳param = {'_stp': str(_stp),#时间戳是一个参数'unikey': url + tid + '.1<.>' + url + '.1','g_tk': [g_tk, g_tk],'face': '0','fupdate': '1','qzonetoken': qzonetoken}respond = sessions.get('https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/user/qz_opcnt2',params=param,headers=headers,cookies=cookie)r = re.sub("_Callback","",respond.text)test = r[1:-2]if test == None or test == "" or len(test) == 0:print("lose data")continueelse:try:Data = json.loads(test)likenum = Data['data'][0]['current']['likedata']['cnt']cur.execute("update qqzoneinfo set likenum = "+str(likenum)+" where id = "+str(idc))conn.commit()print('like:'+str(likenum))print(idc)ran = random.random()time.sleep(1+ran)#增加随机性,1-2秒访问一次except:print("error")

第2条链接的unikey参数一般是按照多条(例如20条)说说的tid进行组装,再访问链接,但是为了方便访问和解析,这里我每次只访问一条说说,这样unikey的组装相对简单明了,返回的响应正问也结构清楚,这样做的唯一缺点就是效率降低很多,只能一条条爬,按照每条1-2秒计算,如果中途不出问题,1800条至少要30min~1h,因此这部分可以根据情况改进,比如多线程、并行等都可以。

爬取点赞数代码的原理是不断访问数据库剩余未爬取点赞数的说说,while循环获取点赞数,直到全部获取为止。

以上就是全部的爬取代码。

  • 可视化分析部分——

爬取了所有的说说数据,就可以做任何想做的可视化咯。可视化可以用echarts的python版本,非常方便,链接在http://pyecharts.org

以下有一些分析的效果图,用了Scatter3D,Scatter,Bar,Pie,HeatMap这些基本表。

分析之后可以发现,大学之前的点赞和评论都极少,说明人际交友等都很少,大学之后(2014-2018)这段期间,虽然说说发表的数量每年都在减少,话越来越少,但是获得高赞和高评论的次数似乎不减反增,说明交际的质量提高了。查看一下点赞数和评论数最高的十条说说,不尽相同,也非常有意思,如下图。

女票霸榜了!有种重翻日记本的感觉~

最后也可以做成日历热力图,可以把每年的说说都展示出来,频数一目了然。这里就展示出两年的图。

以上就是最近这个idea的实现,完整的数据爬取和数据可视化的流程,feeling good。这篇文章核心是分享下爬虫的写法,因此只展示了爬虫部分的代码。可视化代码相对简单,有空再把可视化的代码展示一下~

通过Python爬取QQ空间说说并通过Pyechart进行可视化分析相关推荐

  1. php取qq空间说说id,Python爬取qq空间说说的实例代码

    具体代码如下所示: #coding:utf-8 #!/usr/bin/python3 from selenium import webdriver import time import re impo ...

  2. python爬取qq空间锁密图片_Python3爬取QQ空间信息(下)

    |下载W3Cschool手机App,0基础随时随地学编程>>戳此了解| 导语 内容回顾: Python爬取QQ空间信息(上) 按照(上)中的安排,本期内容为抓取QQ空间的好友信息并做可视化 ...

  3. 用python爬取qq空间内容_利用Fiddler抓包和py的requests库爬取QQ空间说说内容并写入文件...

    [Python] 纯文本查看 复制代码#!C:\Program Files\Python36 python # -*- coding: UTF-8 -*- """ @au ...

  4. python爬取QQ空间好友说说并生成词云

    最近自己玩爬虫玩得很嗨.想到爬QQ空间主要是因为在看网课的时候有不少人刷弹幕要去爬前女友空间..咳咳,虽然我没有前女友,但是这不失为一个有趣的练手机会.(爬完之后发现不会留下访客记录!确实很适合爬前女 ...

  5. 用python爬取qq空间内容_用python爬取QQ空间

    原博文 2016-11-18 17:19 − 好久没写博文了,最近捣鼓了一下python,好像有点上瘾了,感觉python比js厉害好多,但是接触不久,只看了<[大家网]Python基础教程(第 ...

  6. 看qq加密相册_用 Python 爬取 QQ 空间说说和相册

    QQ 空间在 2005 年被腾讯开发,已经经历了 15 个年头,在还没有微信的年代,看网友发表的心情.心事.照片大多都在 QQ 空间的里.它承载了80.90 后的大量青春,下面我们一起用 seleni ...

  7. python爬取qq空间说说

    模块:selenium,pyquery,json,time 使用的是:Chrome 遇到的问题: 模拟点击下一页操作,需要换方式. 遇到元素在frame,需要进入查找. 对空间的登陆进行分析 进入网址 ...

  8. 用 Python 爬取 QQ 空间说说和相册

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 君不见走马川行雪海边,平沙莽莽黄入 ...

  9. Python 爬取 QQ 空间说说和相册

    QQ 空间在 2005 年被腾讯开发,已经经历了 15 个年头,在还没有微信的年代,看网友发表的心情.心事.照片大多都在 QQ 空间的里.它承载了80.90 后的大量青春,下面我们一起用 seleni ...

最新文章

  1. 喜马拉雅音频下载工具
  2. linux安装java_linux中替换系统自带的OpenJDK
  3. 基本概念学习(8000)---兼容机
  4. 表达式求值负数乘负数_为什么现在很多期权的时间价值都为负数?
  5. GPS基站架设完整操作流程
  6. 2020研究生数学建模结果_关于举办2020年全国研究生数学建模大赛的通知
  7. 测视力距离5米还是3米_多功能视力表灯箱的用法
  8. 面试宝典系列-Mysql索引的区别
  9. linux下的僵尸进程 - Zombie
  10. windows server 2003 IIS 调试 ASP时路径问题
  11. 【1】redis的安装和配置,以及简单的增删查改uinx命令
  12. Zabbix3 ——Server端的安装配置小结
  13. python数据标注工具_使用Python实现简易的数据标注工具
  14. 安捷伦的仪器设备出售
  15. 史上最全的点线面距离公式与推导过程(图文介绍)
  16. Failed to load language: zh-CN from的解决办法
  17. LICEcap:GIF屏幕录制工具
  18. 百度地图LBS应用开发代码
  19. 无法打开内核设备“\.\VMCIDev\VMX”: 操作成功完成。是否在安装 VMware Workstation 后重新引导? 模块“DevicePowerOn”启动失败。 未能启动虚拟机。
  20. matlab %,Matlab

热门文章

  1. 【SSH】--SSH框架简介
  2. BCB vs. VC++
  3. 我TM究竟应该选哪个版本的MySQL?!
  4. 【Rust日报】2022-02-09 热议帖 - 我TM的做开源没有得到任何资助
  5. 卫士处刑者冠军css3边,流放之路职业开荒路 决斗者冠军双持刀刃乱舞
  6. rtx2060什么水平_RTX2060性能如何?NVIDIA新一代RTX2060显卡评测
  7. 毕业设计论文选题系统系统用例图_毕业设计论文选题系统
  8. glDrawElements 绘制立方体共用顶点的法线和UV处理
  9. 大连理工大学开发区校区新手指南——2.校园介绍篇
  10. mac 触控板手势以及常用快捷键