用 Python 爬取 QQ 空间说说和相册

Irene181
• 阅读 2228

用 Python 爬取 QQ 空间说说和相册

文 | 某某白米饭

来源:Python 技术「ID: pythonall」

用 Python 爬取 QQ 空间说说和相册QQ 空间在 2005 年被腾讯开发,已经经历了 15 个年头,在还没有微信的年代,看网友发表的心情、心事、照片大多都在 QQ 空间的里。它承载了80、90 后的大量青春,下面我们一起用 selenium 模块导出说说和相册回忆青春吧

安装 selenium

selenium 是一个在浏览器中运行,以模拟用户操作浏览器的方式获取网页源码,使用 pip 安装 selenium 模块

pip install selenium  

查看 chrome 浏览器版本并下载 对应的 chrome 浏览器驱动

用 Python 爬取 QQ 空间说说和相册

http://npm.taobao.org/mirrors/chromedriver 网址中找到相同版本的 chrome 驱动,并放在 python 程序运行的同一个文件夹中

登陆

按 F12 检擦网页源代码,找到登录和密码的文本框,如下图所示

用 Python 爬取 QQ 空间说说和相册

def login(login_qq,password, business_qq):  
    '''  
    登陆  
    :param login_qq: 登陆用的QQ  
    :param password: 登陆的QQ密码  
    :param business_qq: 业务QQ  
    :return: driver  
    '''  
    driver = webdriver.Chrome()  

    driver.get('https://user.qzone.qq.com/{}/311'.format(business_qq))  # URL  
    driver.implicitly_wait(10)  # 隐示等待,为了等待充分加载好网址  
    driver.find_element_by_id('login_div')  
    driver.switch_to.frame('login_frame')  # 切到输入账号密码的frame  
    driver.find_element_by_id('switcher_plogin').click()  ##点击‘账号密码登录’  
    driver.find_element_by_id('u').clear()  ##清空账号栏  
    driver.find_element_by_id('u').send_keys(login_qq)  # 输入账号  
    driver.find_element_by_id('p').clear()  # 清空密码栏  
    driver.find_element_by_id('p').send_keys(password)  # 输入密码  
    driver.find_element_by_id('login_button').click()  # 点击‘登录’  
    driver.switch_to.default_content()  

    driver.implicitly_wait(10)  
    time.sleep(5)  

    try:  
        driver.find_element_by_id('QM_OwnerInfo_Icon')  
        return driver  
    except:  
        print('不能访问' + business_qq)  
        return None  

说说

登录 QQ 后默认的页面就在说说的界面,显示一页的说说是滚动加载的,必须要多次下拉滚动条后才能获取到该页所有的说说,然后用 BeautifulSoup 模块构建对象解析页面,下图是放说说的 iframe

用 Python 爬取 QQ 空间说说和相册

def get_shuoshuo(driver):  

    page = 1  
    while True:  
        # 下拉滚动条  
        for j in range(1, 5):  
            driver.execute_script("window.scrollBy(0,5000)")  
            time.sleep(2)  

        # 切换 frame  
        driver.switch_to.frame('app_canvas_frame')  
        # 构建 BeautifulSoup 对象  
        bs = BeautifulSoup(driver.page_source.encode('GBK', 'ignore').decode('gbk'))  
        # 找到页面上的所有说说  
        pres = bs.find_all('pre', class_='content')  

        for pre in pres:  
            shuoshuo = pre.text  
            tx = pre.parent.parent.find('a', class_="c_tx c_tx3 goDetail")['title']  
            print(tx + ":" + shuoshuo)  

        # 页数判断  
        page = page + 1  
        maxPage = bs.find('a', title='末页').text  

        if int(maxPage) < page:  
            break  

        driver.find_element_by_link_text(u'下一页').click()  
        # 回到主文档  
        driver.switch_to.default_content()  
        # 等待页面加载  
        time.sleep(3)  

相册

下载相册里面的照片需要 selenium 模块模拟鼠标一步步点击页面,先点击上方的相册按钮,进去就是多个相册的列表,下图是单个相册的超链接

用 Python 爬取 QQ 空间说说和相册

在单个相册中点击照片,界面如下图

用 Python 爬取 QQ 空间说说和相册

def get_photo(driver):  

    # 照片下载路径  
    photo_path = "C:/Users/xxx/Desktop/photo/{}/{}.jpg"  

    # 相册索引  
    photoIndex = 1  

    while True:  
        # 回到主文档  
        driver.switch_to.default_content()  
        # driver.switch_to.parent_frame()  
        # 点击头部的相册按钮  
        driver.find_element_by_xpath('//*[@id="menuContainer"]/div/ul/li[3]/a').click()  
        #等待加载  
        driver.implicitly_wait(10)  
        time.sleep(3)  
        # 切换 frame  
        driver.switch_to.frame('app_canvas_frame')  
        # 各个相册的超链接  
        a = driver.find_elements_by_class_name('album-cover')  
        # 单个相册  
        a[photoIndex].click()  

        driver.implicitly_wait(10)  
        time.sleep(3)  
        # 相册的第一张图  
        p = driver.find_elements_by_class_name('item-cover')[0]  
        p.click()  
        time.sleep(3)  

        # 相册大图在父frame,切换到父frame  
        driver.switch_to.parent_frame()  
        # 循环相册中的照片  
        while True:  
            # 照片url地址和名称  
            img = driver.find_element_by_id('js-img-disp')  
            src = img.get_attribute('src').replace('&t=5', '')  
            name = driver.find_element_by_id("js-photo-name").text  

            # 下载  
            urlretrieve(src, photo_path.format(qq, name))  

            # 取下面的 当前照片张数/总照片数量  
            counts = driver.find_element_by_xpath('//*[@id="js-ctn-infoBar"]/div/div[1]/span').text  

            counts = counts.split('/')  
            # 最后一张的时候退出照片浏览  
            if int(counts[0]) == int(counts[1]):  
                # 右上角的 X 按钮  
                driver.find_element_by_xpath('//*[@id="js-viewer-main"]/div[1]/a').click()  
                break  
            # 点击 下一张,网页加载慢,所以10次加载  
            for i in (1, 10):  
                if driver.find_element_by_id('js-btn-nextPhoto'):  
                    n = driver.find_element_by_id('js-btn-nextPhoto')  
                    ActionChains(driver).click(n).perform()  
                    break  
                else:  
                    time.sleep(5)  

        # 相册数量比较,是否下载了全部的相册  
        photoIndex = photoIndex + 1  
        if len(a) <= photoIndex:  
            break  

示例结果

用 Python 爬取 QQ 空间说说和相册

总结

大家在看十几年前的说说和照片是不是感觉满满的黑历史快要溢出屏幕了。时光荏苒、岁月如梭,愿一切安好。

**-----**------**-----**---**** End **-----**--------**-----**-****

往期精彩文章推荐:

用 Python 爬取 QQ 空间说说和相册

欢迎各位大佬点击链接加入群聊【helloworld开发者社区】:https://jq.qq.com/?_wv=1027&k=mBlk6nzX进群交流IT技术热点。

本文转自 https://mp.weixin.qq.com/s/05YvMwzVy8n84fKXWo4y9w,如有侵权,请联系删除。

点赞
收藏
评论区
推荐文章
浅梦一笑 浅梦一笑
1个月前
初学 Python 需要安装哪些软件?超级实用,小白必看!
编程这个东西是真的奇妙。对于懂得的人来说,会觉得这个工具是多么的好用、有趣,而对于小白来说,就如同大山一样。其实这个都可以理解,大家都是这样过来的。那么接下来就说一下python相关的东西吧,并说一下我对编程的理解。本人也是小白一名,如有不对的地方,还请各位大神指出01名词解释:如果在编程方面接触的比较少,那么对于软件这一块,有几个名词一定要了解,比如开发环
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。 1、使用解构获取json数据let jsonData   id: 1, status: "OK", data: ['a', 'b'] ; let  id, status, data: number   jsonData; console.log(id, status, number )
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
Easter79 Easter79
1年前
swap空间的增减方法
(1)增大swap空间 去激活swap交换区: #swapoff -v /dev/vg00/lvswap 扩展交换lv: #lvextend -L 10G /dev/vg00/lvswap 重新生成swap交换区: #mkswap /dev/vg00/lvswap 激活新生成的交换区: #swapon -v /dev/vg00/lvswap
Stella981 Stella981
1年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有`time`,和`datetime`两个,本文先说`time`模块。 ### 关于时间戳的几个概念 * 时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。 * 时间元组(`struct_time`),包含9个元素。  `time.struct_time(tm_y
Wesley13 Wesley13
1年前
MySQL查询按照指定规则排序
1.按照指定(单个)字段排序 select * from table_name order id desc; 2.按照指定(多个)字段排序 select * from table_name order id desc,status desc; 3.按照指定字段和规则排序 selec
Stella981 Stella981
1年前
Django中Admin中的一些参数配置
### **设置在列表中显示的字段,id为django模型默认的主键** list_display = ('id', 'name', 'sex', 'profession', 'email', 'qq', 'phone', 'status', 'create_time') ### **设置在列表可编辑字段** list_editable
Stella981 Stella981
1年前
Angular material mat
Icon Icon Name mat-icon code _add\_comment_ add comment icon <mat-icon> add\_comment</mat-icon> _attach\_file_ attach file icon <mat-icon> attach\_file</mat-icon> _attach\
Wesley13 Wesley13
1年前
oracle:ORA
报ORA-25153,这一定是临时表空间逻辑名还在,但是找不到临时文件的原因。 解决方法: 1、查询临时表空间状态状态 select tablespace\_name,status from dba\_tablespaces; TABLESPACE\_NAME STATUS \--------- SYSTEM ONL
Wesley13 Wesley13
1年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
#### 背景描述 # Time: 2019-01-24T00:08:14.705724+08:00 # User@Host: **[**] @ [**] Id: ** # Schema: sentrymeta Last_errno: 0 Killed: 0 # Query_time: 0.315758 Lock_
helloworld_34035044 helloworld_34035044
4个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为