browser.quit() return (cookie,gtk,g_qzonetoken.group(1)) if name==“main”: QR_login()
通过Requests库利用前面得到的url参数,构造http请求
通过抓包分析可以找到上图这个请求,这个请求响应的是说说信息
通过火狐浏览器的一个叫json-dataview的插件可以看到这个响应是一个json格式的,开心!
然后就是用正则表达式提取字段了,这个没什么意思,直接看我的代码吧
def parse_mood(i): ‘’‘从返回的json中,提取我们想要的字段’‘’ text = re.sub(‘“commentlist”:.*?“conlist”:’, ‘’, i) if text: myMood = {} myMood[“isTransfered”] = False tid = re.findall(‘“t1_termtype”:.?“tid”:"(.?)"’, text)[0] # 获取说说ID tid = qq + ‘_’ + tid myMood[‘id’] = tid myMood[‘pos_y’] = 0 myMood[‘pos_x’] = 0 mood_cont = re.findall(‘],“content”:“(.*?)”’, text) if re.findall(‘},“name”:“(.*?)”,’, text): name = re.findall(‘},“name”:“(.*?)”,’, text)[0] myMood[‘name’] = name if len(mood_cont) == 2: # 如果长度为2则判断为属于转载 myMood[“Mood_cont”] = “评语:” + mood_cont[0] + “--------->转载内容:” + mood_cont[1] # 说说内容 myMood[“isTransfered”] = True elif len(mood_cont) == 1: myMood[“Mood_cont”] = mood_cont[0] else: myMood[“Mood_cont”] = “” if re.findall(‘“created_time”😦\d+)’, text): created_time = re.findall(‘“created_time”😦\d+)’, text)[0] temp_pubTime = datetime.datetime.fromtimestamp(int(created_time)) temp_pubTime = temp_pubTime.strftime(“%Y-%m-%d %H:%M:%S”) dt = temp_pubTime.split(’ ') time = dt[1] myMood[‘time’] = time date = dt[0] myMood[‘date’] = date if re.findall(‘“source_name”:“(.*?)”’, text): source_name = re.findall(‘“source_name”:“(.*?)”’, text)[0] # 获取发表的工具(如某手机) myMood[‘tool’] = source_name if re.findall(‘“pos_x”:“(.*?)”’, text):#获取经纬度坐标 pos_x = re.findall(‘“pos_x”:“(.*?)”’, text)[0] pos_y = re.findall(‘“pos_y”:“(.*?)”’, text)[0] if pos_x: myMood[‘pos_x’] = pos_x if pos_y: myMood[‘pos_y’] = pos_y idname = re.findall(‘“idname”:“(.*?)”’, text)[0] myMood[‘idneme’] = idname cmtnum = re.findall(‘“cmtnum”😦.*?),’, text)[0] myMood[‘cmtnum’] = cmtnum return myMood#返回一个字典 我们想要的东西已经提取出来了,接下来需要设计数据表,通过navicat可以很方便的建表,然后通过python连接mysql数据库,写入数据。这是创建数据表的sql代码 CREATE TABLE mood ( name varchar(80) DEFAULT NULL, date date DEFAULT NULL, content text, comments_num int(11) DEFAULT NULL, time time DEFAULT NULL, tool varchar(255) DEFAULT NULL, id varchar(255) NOT NULL, sitename varchar(255) DEFAULT NULL, pox_x varchar(30) DEFAULT NULL, pox_y varchar(30) DEFAULT NULL, isTransfered double DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 其实到这里爬虫的主要的代码就算完了,之后主要是通过QQ邮箱的联系人导出功能,构建url列表,最后等着它运行完成就可以了。这里我单线程爬200多个好友用了大约三个小时,拿到了十万条说说。下面是爬虫的主体代码。 #从csv文件中取qq号,并保存在一个列表中 csv_reader = csv.reader(open(‘qq.csv’)) friend=[] for row in csv_reader: friend.append(row[3]) friend.pop(0) friends=[] for f in friend: f=f[:-7] friends.append(f) headers={ ‘Host’: ‘h5.qzone.qq.com’, ‘User-Agent’: ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0’, ‘Accept’: ‘/’, ‘Accept-Language’:‘zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3’, ‘Accept-Encoding’: ‘gzip, deflate, br’, ‘Referer’: ‘https://user.qzone.qq.com/790178228?t=0.22746974226377736’, ‘Connection’:‘keep-alive’ }#伪造浏览器头 conn = MySQLdb.connect(‘localhost’, ‘root’, ‘123456’, ‘qq_mood’, charset=“utf8”, use_unicode=True)#连接mysql数据库 cursor = conn.cursor()#定义游标 cookie,gtk,qzonetoken=QRlogin#通过登录函数取得cookies,gtk,qzonetoken s=requests.session()#用requests初始化会话 for qq in friends:#遍历qq号列表 for p in range(0,1000): pos=p*20 params={ ‘uin’:qq, ‘ftype’:‘0’, ‘sort’:‘0’, ‘pos’:pos, ‘num’:‘20’, ‘replynum’:‘100’, ‘g_tk’:gtk, ‘callback’:‘_preloadCallback’, ‘code_version’:‘1’, ‘format’:‘jsonp’, ‘need_private_comment’:‘1’, ‘qzonetoken’:qzonetoken } response=s.request(‘GET’,‘https://h5.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6’,params=params,headers=headers,cookies=cookie) print(response.status_code)#通过打印状态码判断是否请求成功 text=response.text#读取响应内容 if not re.search(‘lbs’, text):#通过lbs判断此qq的说说是否爬取完毕 print(‘%s说说下载完成’% qq) break textlist = re.split(‘{“certified”’, text)[1:] for i in textlist: myMood=parse_mood(i) ‘’‘将提取的字段值插入mysql数据库,通过用异常处理防止个别的小bug中断爬虫,开始的时候可以先不用异常处理判断是否能正常插入数据库’‘’ try: insert_sql = ‘’’ insert into mood(id,content,time,sitename,pox_x,pox_y,tool,comments_num,date,isTransfered,name) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ‘’’ cursor.execute(insert_sql, (myMood[‘id’],myMood[“Mood_cont”],myMood[‘time’],myMood[‘idneme’],myMood[‘pos_x’],myMood[‘pos_y’],myMood[‘tool’],myMood[‘cmtnum’],myMood[‘date’],myMood[“isTransfered”],myMood[‘name’])) conn.commit() except: pass print(‘说说全部下载完成!’)
下面是爬取的数据,有100878条!(没想到居然有这么多)
拿到数据后,我先用sql进行聚合分析,然后通过ipython作图,将数据可视化。
统计一年之中每天的说说数目,可以发现每年除夕这一天是大家发说说最多的一天(统计了2013到2017年)
通过两个辅助表,可以看到分年,分月,分小时段统计的说说数目,下面是代码和数据图
其余的几个图代码都是类似的,我就不重复发了。(其实主要是cmd里面复制代码太不方便了,建议大家用ipython notebook)
额,可以看出2014年9月达到了一个高峰,主要是因为我的朋友大都是是2014年九月大学入学的,之后开始下降,这可能是好多人开始玩微信,逐渐放弃了QQ,通过下面这个年变化图可以更直观的看出
通过这个每小时段说说发表的数目柱形图,可以发现大家在晚上22点到23点左右是最多的,另外中午十二点到一点也有一个小高峰
tool发表说说用的工具这个字段的数据比较脏,因为发表工具可以由用户自定义。最后我用Excel的内容筛选功能,做了一个手机类型的饼图
做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。
别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。
我先来介绍一下这些东西怎么用,文末抱走。
(1)Python所有方向的学习路线(新版)
这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
最近我才对这些路线做了一下新的更新,知识体系更全面了。
(2)Python学习视频
包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。
(3)100多个练手项目
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。
(4)200多本电子书
这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。
基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。
(5)Python知识点汇总
知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。
(6)其他资料
还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。