主要思路:
- 通过
selenium+phantomjs
模拟登录qq
空间取到cookies
和g_qzonetoken
,并算出gtk
- 通过
Requests
库利用前面得到的url
参数,构造http
请求
- 分析请求得到的响应,是一个
json
,利用正则表达式提取字段
- 设计数据表,并将提取到的字段插入到数据库中
- 通过
qq
邮箱中的导出联系人功能,把好友的qq
号导出到一个csv文件,遍历所有的qq
号爬取所有的说说
- 通过
sql
查询和ipython
分析数据,并将数据可视化
- 通过
python
的第三方库jieba
、wordcloud
基于说说的内容做一个词云
- 通过
selenium+phantomjs
模拟登录qq
空间取到cookies
和g_qzonetoken
,并算出gtk
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import re from selenium import webdriver from time import sleep from PIL import Image def QR_login(): def getGTK(cookie): """ 根据cookie得到GTK """ hashes = 5381 for letter in cookie['p_skey']: hashes += (hashes << 5) + ord(letter) return hashes & 0x7fffffff browser=webdriver.PhantomJS(executable_path="D:\phantomjs.exe") url="https://qzone.qq.com/" browser.get(url) browser.maximize_window() sleep(3) browser.get_screenshot_as_file('QR.png') im = Image.open('QR.png') im.show() sleep(20) print(browser.title) cookie = {} for elem in browser.get_cookies(): cookie[elem['name']] = elem['value'] print('Get the cookie of QQlogin successfully!(共%d个键值对)' % (len(cookie))) html = browser.page_source g_qzonetoken=re.search(r'window\.g_qzonetoken = \(function\(\)\{ try\{return (.*?);\} catch\(e\)',html) gtk=getGTK(cookie) browser.quit() return (cookie,gtk,g_qzonetoken.group(1)) if __name__=="__main__": QR_login()
|
通过火狐浏览器的一个叫json-dataview
的插件可以看到这个响应是一个json
格式的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| 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] 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: 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
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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多个好友用了大约三个小时,拿到了十万条说说。下面是爬虫的主体代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| 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) cursor = conn.cursor() cookie,gtk,qzonetoken=QRlogin s=requests.session() for qq in friends: 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): 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('说说全部下载完成!')
|
数据分析
学生QQ用的多还是微信用的多?
- 先用
sql
进行聚合分析,然后通过ipython
作图,将数据可视化。
统计一年之中每天的说说数目,可以发现每年除夕这一天是大家发说说最多的一天,可以看出2015年9月达到了一个高峰,主要因为数据是2015级的,所以在2015年九月大学入学的,之后开始下降,好多人开始玩微信,逐渐放弃了QQ,所以北石化学生用微信还是多。
- 通过下面这个年变化图可以更直观的看出QQ使用的频率越来越少,可能因为大学里班级,社团,活动有很多的微信群,越来越少的北石化学生使用QQ。
学生晚上几点睡觉?
通过这个每小时段说说发表的数目柱形图,可以发现大家在晚上22点到23点左右是最多的,另外中午十二点到一点也有一个小高峰!由此可见大多数学生在宿舍十一点熄灯后,并不会按时睡觉。
学生的经济情况怎么样?
用Excel的内容筛选功能,做了一个手机类型的饼图,通过这个饼图可以看出使用最多的手机是苹果,小米,魅族,华为这四个手机品牌,说明大多数大学生还是比较倾向于性价比比较高的手机,从某一方面可以体现大多数同学还是中等生活水平。
学生都在说些什么?
通过将mood
表中的content
字段导出为txt文本文件,利用python
的jieba
和wordcloud
这两个第三方库,可以生成基于说说内容的词云.看看大家在国庆期间都再说些什么,很明显关于,习近平主席,国庆节,人民英雄纪念碑等关键词明显增多,同样也有计算机,英语,考试等关于学习的字段。
,