用python爬取QQ空间说说

技术教程 · 2017-09-24

最近在学习python这门脚本语言,不得不说,python用来爬去网页数据简直不能太方便。学习一门编程语言,最好的方法就是在实践中学习。之前我一直想把我这些年来QQ空间里发布的说说爬下来分析一下,于是就有了这个项目。

要爬网页数据,基本步骤就是:模拟登录(如果需要的话)->保存网页数据->使用第三方库beautifulsoup分析网页数据->保存需要的数据->翻页,继续爬取(如果有必要的)

刚开始,我打算把这些数据同步到这里的,后来看了一下数据那么多,就算了。

先看看我昨天爬取的结果吧,我只是统计了发布时间,后期如果有时间的话,会继续统计点赞和评论情况。
源码在文章最后,仅作参考
按年份.png

从年份来看,12 13 14这三年是我发说说最频繁的三年,因为这三年是我临近大学毕业,培训,实习和找工作的时期,所以不免会遇到各种奇葩,不顺心,开心和各种事情,所以发说说感慨一下也是情理之中。

14年之后,说说数量明显减少,主要是因为各种动态和心情都发布在微信朋友圈了。

08 09年发布的说说为什么会那么少?

原因有两个:
1.08年刚开始用QQ空间,发布的说说少可以理解;
2.08 09年发布的说说大多是没有营养,或者是比较悲观愤青的文字,所以删除了很多

按月份.png

从月份来看,每个月的数量基本持平,9 10月份稍微多一些,估计是因为那时是开学时期,各种新鲜事吧。

按日期.png

从日期来看,也是差不多,31号明显偏少,是因为不是每个月都有31号吧

按时间.png

从24小时趋势来看,每个时间段都有发说说,我居然熬夜那么晚,或者还通宵了。晚上11 12点发说说比较多,这符合夜猫子习惯。

好了,言归正传,说一下整个爬取过程。

爬取用到的工具和库:
python
BeautifulSoup
Selenium
lxml
re
SublimeText
这些库安装就不再赘述了,反正就是很麻烦,装了很久,有些库还有依赖关系,有些用pip install命令还装不了。

首先导入各种库和模块

#coding=utf-8
#导入selenium2中的webdriver库
from selenium import webdriver
import time
from bs4 import BeautifulSoup
import re

然后用selenium模拟登录到QQ空间

def login(driver, qq):
    #设置浏览器窗口的位置和大小
    driver.set_window_position(20, 40)
    driver.set_window_size(1100,700)

    #打开一个页面(QQ空间登录页)
    driver.get('http://user.qzone.qq.com/%d/311'%qq)
    #登录表单在页面的框架中,所以要切换到该框架
    time.sleep(1)
    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(5)
        # 这里必须要切换一下frame,否则获取不到说说内容
    driver.switch_to_frame('app_canvas_frame')
    time.sleep(2)
        #获取html源码
        return driver.page_source

获取到说说页面的原始html代码后,使用beautifulsoup去解析

#获取html源码
pages = login(driver,qq) 
#使用lxml作为bs的解析器
soup = BeautifulSoup(pages,'lxml')
#这里是获取总说说数量
items = soup.find('a', class_='c_tx goProfile').get_text()
#获取总页面数量
pages = soup.find('a', id='pager_last_0').get_text()
#这里才是当前页面说说列表
ol = soup.find('ol', id='msgList')

获取到页面说说列表后,我们就可以按照自己的需求去获取数据了。

先来看看一条说说包含的数据
说说.png

主要分为四大部分:说说文字部分,图片和视频部分,发布时间和赞评论数,评论列表(包含了点赞人员列表)
这几个部分分别在一下几个div中:

知道了这些信息之后就可以写代码了。

先写几个函数分别解析以上几个部分数据,
先获取说说文字部分
文字部分.png
然后是图片部分
图片部分.png
发布时间部分
发布时间.png
点赞列表
点赞列表.png
评论部分
评论部分.png
因为评论部分的结构最新说说和旧的说说的结构还不一样,所以这部分的代码有点多

接下来写个while循环来获取数据
循环主体.png

跑出来的数据大概是这样的
说说list.png

爬取了说说文字,图片,发布时间,点赞列表,评论等信息,说说文字内容中的表情和评论内容中的表情无法解析出来。

遇到一个问题:QQ空间页面加载并不是一次性把所有说说的图片和评论加载出来,所以按照一般获取html源码是获取的话,后面的说说评论部分会获取不到,一个比较折中的方法是用selenium模拟滚动页面以让浏览器加载所有说说的评论内容,这个方法的缺点就是需要时间比较长,如果网络差的话,有些评论还是会获取不到。不过从结果来看,还能接受。

源代码:get_qzone_msg.py
不建议直接运行,因为你会发现你会缺少各种库
时间比较匆忙,没整理代码,只能说能运行,效率上肯定不行,容错能力很差。

python bs4 selenium
  1. 鸟屋 (作者)  2017-10-16
    @tecmry

    不会吧,所以我用selenium来模拟用户拖动页面以获取元素

  2. tecmry 2017-10-15

    没用啊 QQ空间并不是直接加载你获取源代码跟元素不同

  3. Knight 2017-09-25
    @不稽一格

    还没完善好,遇到一些难题了 @(xiaoguai)

  4. 不稽一格 2017-09-25

    好高级,看不懂

Theme Jasmine by Kent Liao