700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 通过Python爬取QQ空间说说并通过Pyechart进行可视化分析

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

时间:2018-10-01 05:48:53

相关推荐

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

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

用到的库——

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

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

QQ空间说说板块分析——

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

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

https://h5./proxy/domain//cgi-bin/emotion_cgi_msglist_v6https://user./proxy/domain/r./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)mit()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(无界面的浏览器),下载的链接在这/download.html,可以下载对应版本。使用时只需在webdriver.PhantomJS()中把phantomjs.exe的路径赋给executable_path即可。虽然selenium现在的版本好像已经把phantomjs剔除了,但是似乎不影响使用。

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

#coding = 'utf-8'from selenium import webdriverimport requestsimport jsonfrom lxml import etreefrom bs4 import BeautifulSoupimport sqlite3import reimport timeimport 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 = "/"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']))mit()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./proxy/domain//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./你的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./proxy/domain/r./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))mit()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版本,非常方便,链接在

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

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

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

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。