[Python]消失在QQ空间里的青春

开发 后端 移动开发
QQ空间,这个曾经陪我们从童年到少年再到成年,从2G时代再到如今的4G末,占据了我们太多的青春回忆,如今好友空间动态更新的不在像从前那样频繁。

QQ空间,这个曾经陪我们从童年到少年再到成年,从2G时代再到如今的4G末,占据了我们太多的青春回忆,如今好友空间动态更新的不在像从前那样频繁。依稀记得当年的好友买卖,抢车位再或者情侣空间,现在想想那时候真的很幼稚,那就是我们傻逼的童年,什么互踩,火星文,跑堂见证了我们无忧无虑的童年。

有时候看看QQ推送的"那年今日",看到自己好几年前发的动态,说的傻话,自己都怕了自己。有时候看到好朋友几年前的动态,不由笑骂道,这孙子,怎么这么2! 即使现在不怎么用QQ了,有时候看看曾经发的说说还有空间的留言。即使让我再尴尬也不舍得删,因为那都是青春满满的回忆。

空间留言上千条,说说也比较多,一页一页的翻比较麻烦。索性就把这些数据都下载到本地。同理我们也可以导出全部联系人的说说和留言板。

Selenium

由于访问好友留言板需要登录,为了方便起见我们使用Web应用程序测试的Selenium工具。该工具可以用于单元测试,集成测试,系统测试等等。它可以像真正的用户一样去操作浏览器等,支持Mozilla Firefox、Google Chrome、Safari、Opera、IE等等浏览器。

使用这个工具之前我们需要安装selenium库和下载相应浏览器的驱动。然后通过分析QQ空间登录界面我们发现默认是扫码登录,因此需要切换成账号密码登录。

[Python]消失在QQ空间里的青春

通过分析html标签属性,我们发现 id="switcher_plogin",是个切换登录的全局唯一属性。同理我们再需要找到账号、密码输入框和点击登录的元素就可以用selenium模拟登录了

[Python]消失在QQ空间里的青春

登录部分代码如下:

  1. from selenium import webdriver 
  2.  
  3. driver = webdriver.Chrome() 
  4.     # 获取谷歌浏览器驱动 
  5.     driver = webdriver.Chrome() 
  6.     # 登录网站 
  7.     driver.get('https://i.qq.com'
  8.     # 选择账号密码登录 
  9.     driver.switch_to_frame('login_frame'
  10.     # 点击输入框获取输入 
  11.     driver.find_element_by_id('switcher_plogin').click() 
  12.     # 输入账号 
  13.     driver.find_element_by_id('u').send_keys('你的qq号'
  14.     # 输入密码 
  15.     driver.find_element_by_id('p').send_keys('qq密码'
  16.     # 点击登录 
  17.     driver.find_element_by_id('login_button').click() 

工作前的参数准备

通过查看开发者工具中的请求我们发现,登录之后每次请求除了携带必要的参数以外,还携带了登录获取的token和g_tk。token我们可以从网页源代码中直接获取,但是g_tk在源代码中没有,根据以往经验第一步只能从js中查看,果然发现了一段加密代码,再结合上下文发现是从cookie中取出“p_skey”的值再经过一系列操作就是g_tk的值了。因为我们需要先获取cookie,然后再通过cookie获取g_tk。

[Python]消失在QQ空间里的青春

部分js加密逻辑代码

  1. if (e) { 
  2.      if (e.host && e.host.indexOf("qzone.qq.com") > 0) { 
  3.         try { 
  4.            t = parent.QZFL.cookie.get("p_skey"
  5.         } catch(e) { 
  6.            t = QZFL.cookie.get("p_skey"
  7.         } 
  8.      }  
  9.         ............ 
  10.   } 
  11.  
  12. "g_tk=" + QZFL.pluginsDefine.getACSRFToken(t) 
  13.  
  14. QZFL.pluginsDefine.getACSRFToken._DJB = function(e) { 
  15.         var t = 5381; 
  16.         for (var n = 0, 
  17.         r = e.length; n < r; ++n) { 
  18.             t += (t << 5) + e.charCodeAt(n) 
  19.         } 
  20.         return t & 2147483647 
  21.     }; 

获取token && cookie && g_tk代码

  1. ""
  2.  获取g_tk的值 
  3. ""
  4. def get_g_tk(cookie): 
  5.     hashes = 5381 
  6.     for letter in cookie['p_skey']: 
  7.         hashes += (hashes << 5) + ord(letter) 
  8.     return hashes & 0x7fffffff 
  9.  
  10. # 获取登录之后的cookie信息 
  11. cookie = {} 
  12. for elem in driver.get_cookies(): 
  13.     cookie[elem['name']] = elem['value'
  14. # 获取g_tk 
  15. g_tk = get_g_tk(cookie) 
  16. # 利用xpath获取登录之后的网页源代码 
  17. html = driver.page_source 
  18. xpath = r'window\.g_qzonetoken = \(function\(\)\{ try\{return "(.*?)";}' 
  19. # 通过xpath 获得登录后的token 
  20. token = re.compile(xpath).findall(html)[0] 

开始搞事

破解了一个简单的反爬虫,下面就可以编写正式的爬虫代码了,首先确定我们目标url、通过浏览器分析响应的json对象、编写headers

因为每次请求都需要携带登录信息,为了方便我们用到了session类,其次观察相应我们发现返回的response有无用的字符,因此需要进行截取

[Python]消失在QQ空间里的青春

  1. headers = { 
  2.     'authority''user.qzone.qq.com'
  3.     'method''GET'
  4.     'scheme''https'
  5.     'accept-language''zh-CN,zh;q=0.9'
  6.     'user-agent''Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
  7.  
  8. def get_resp(cookie, g_tk, token, page): 
  9.     session = requests.session() 
  10.     # 将cookie字典转换成RequestsCookieJar 
  11.     c = requests.utils.cookiejar_from_dict(cookie) 
  12.     # 将headers 放入session 
  13.     session.headers = headers 
  14.     # RequestsCookieJar复制给session 
  15.     session.cookies = c 
  16.     # 访问留言板的url 
  17.     url = f'https://user.qzone.qq.com/proxy/domain/m.qzone.qq.com/cgi-bin/new/get_msgb?uin={登陆的qq}&hostUin={要查询留言内容的QQ号}&start={page}&num=10&g_tk={g_tk}&qzonetoken={token}' 
  18.     print(url) 
  19.     response = session.get(url) 
  20.     # 截取无用的字符 
  21.     resp_text = response.text[10: -3] 
  22.     # 转为json 
  23.     resp_json = json.loads(resp_text) 
  24.     return resp_json 

上面的方法,只是获得了某一页的接口相应,我们通过json获取留言总数,再除以每页的条数,就可以知道总页数了。然后再遍历去取每页的数据,为了方便查看将数据保存在csv文件中,另外将留言内容保存在txt文件中,生成词云。

  1. def get_zone_xx(cookie, g_tk, token, page=0): 
  2.     # 初始化请求为了取总条数 
  3.     resp_json = get_resp(cookie, g_tk, token, page) 
  4.     # 总条数 
  5.     total = resp_json['data']['total'
  6.     print(f'共{total}条留言信息'
  7.     # 总页数 
  8.     size = int(total/10 + 1) 
  9.     # 已经读取的信息条数 
  10.     use_page = 0 
  11.     # 保存每条数据信息,生成csv文件用 
  12.     content_arr = [] 
  13.     for i in range(0, size): 
  14.         # 请求每一页的内容 
  15.         resp_json = get_resp(cookie, g_tk, token, i) 
  16.         # 当条数大于或等于总条数 跳出循环 
  17.         if use_page >= total: 
  18.             break 
  19.         # 从每页数据中取出需要的字段值 
  20.         for comment in resp_json['data']['commentList']: 
  21.             use_page += 1 
  22.             print(f'当前正在读取第{use_page}条'
  23.             page_json = [] 
  24.             # 留言日期 
  25.             page_json.append(comment['pubtime']) 
  26.             # 昵称 
  27.             page_json.append(comment['nickname']) 
  28.             # 内容 
  29.             content = replace_html(comment['htmlContent']) 
  30.             # 将内容写入文本 生成词云用 
  31.             with open('zone_text111.txt''a'as f: 
  32.                 f.write(content) 
  33.  
  34.             page_json.append(content) 
  35.             content_arr.append(page_json) 

生成csv文件

  1. # 将总数据转化为data frame再输出 
  2.  df = pd.DataFrame(data=content_arr, 
  3.                    columns=['留言日期''昵称''留言内容']) 
  4.  df.to_csv('QQ_ZONE.csv'index=False, encoding='utf-8_sig'
  5.  print('已保存为csv文件.'

运行上面代码生成csv文件部分内容如下

[Python]消失在QQ空间里的青春

生成词云(wordcloud)代码如下

  1. from wordcloud import WordCloud 
  2. import matplotlib.pyplot as plt 
  3. with open('zone_text.txt','r'as f: 
  4.     mytext = f.read() 
  5.  
  6. font = r'C:\Windows\Fonts\simfang.ttf' 
  7. wc = WordCloud(collocations=False, font_path=font, width=1400, height=1400, margin=2).generate(mytext) 
  8. plt.imshow(wc) 
  9. plt.axis("off"
  10. plt.show() 
  11.  
  12. plt.show() 

运行结果如下:

[Python]消失在QQ空间里的青春

写在最后

上面的代码并没有太复杂,也许是触景生情,也许是对现在朋友圈各种乱七八糟的信息产生了抵触,所以试着去回忆青春的那些往事。

朋友圈和空间并不能去衡量一个人是是否成熟,但是对于大部分90后来说,空间真的是承载了太多纯真的回忆。不忘初心,砥砺前行!!!

责任编辑:未丽燕 来源: 程序员共成长
相关推荐

2011-09-14 10:51:34

服务器网络布线APC

2021-05-05 14:00:25

QQ手机QQ移动应用

2015-04-28 13:34:52

phpqq空间发表文章

2009-12-11 14:17:05

Linux平台空间消失

2017-03-18 13:55:00

机器人工作

2015-12-28 13:30:17

模块化数据中心

2019-08-27 10:49:30

跳槽那些事儿技术Linux

2015-08-07 15:32:19

欢迎界面仿微信仿qq空间

2009-05-22 10:11:19

2015-09-09 11:08:48

qq空间可拉伸头部

2019-08-16 17:14:28

跳槽那些事儿技术Linux

2019-05-29 21:21:42

QQH5营销情怀

2017-09-06 15:58:10

华硕商用本

2018-09-26 17:33:37

机器学习人工智能计算机

2017-05-02 09:12:20

QQ空间

2015-10-27 11:14:03

qq腾讯95后

2009-06-09 09:29:33

2017-11-02 15:08:23

智能

2020-05-18 09:43:53

数据中心云服务云计算

2019-10-11 16:29:38

程序员
点赞
收藏

51CTO技术栈公众号