欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

爬取qq好友说说并对数据简单分析

程序员文章站 2022-04-26 08:05:59
...

上一篇介绍了直接爬取的方法,这篇介绍利用Selenium模拟浏览器爬取。Selenium是一个用于Web应用程序测试的工具,它直接运行在浏览器中,就像真实的用户在操作一样。由于这个性质,Selenium也是一个强大的网络数据采集工具,它可以让浏览器自动加载页面。介绍两种方法,一种是Selenium和PhantomJS配合使用,但由于最新版本的Selenium不再支持PhantomJS,所以如果使用PhantomJS需要对Selenium降级。方法:降级方法
然后去PhantomJS官网下载适合自己的版本

爬取qq好友说说并对数据简单分析

下载完成后,解压压缩包,由于PhantomJS路径没有添加到系统路径中,每次编写代码都要手动进行路径的输入。有两个方法可以解决这个问题,一是在系统路径上添加,二是把PhantomJS.exe复制到Python目录下,因为安装的Python路径已经添加到了系统路径中。

测试:在Python环境中输入以下代码进行测试,运行没有出错,说明PhantomJS环境已配置好。

from selenium import webdriver
driver = webdriver.PhantomJS()

另一种方法是使用其他的被Selenium支持的无头浏览器,比如说使用Chrome无头浏览器 使用方法

准备完成后打开 网页版QQ 右键检查
爬取qq好友说说并对数据简单分析
我们需要切到这个frame中,因为我们后面需要定位账号和密码。
右键账号检查
爬取qq好友说说并对数据简单分析
可以看到账号处id=’u’,类似的找到密码id=’p’,登录id=’login_button’
那么进入空间之前的处理如下所示

#登录qq
    try:
        driver.find_element_by_id('login_div')
        a = True
    except:
        a = False
    #a为真时是未登录
    if a == True:
        # print('未登录')
        driver.switch_to.frame('login_frame')
        #切换到账号密码登录
        #click是模拟鼠标点击
        driver.find_element_by_id('switcher_plogin').click()
        driver.find_element_by_id('u').clear()
        driver.find_element_by_id('u').send_keys('填入账号')
        driver.find_element_by_id('p').clear()
        driver.find_element_by_id('p').send_keys('填入密码')
        driver.find_element_by_id('login_button').click()
        #等待加载
        time.sleep(3)
    driver.implicitly_wait(3)

其中的driver如下:
使用PhantomJS时

driver = webdriver.PhantomJS()

使用Chrome时

#设置为无头模式
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(chrome_options=chrome_options)

由于有的空间我们没有权限访问,需要做一些处理。进入空间后,在头像处右键检查
爬取qq好友说说并对数据简单分析
有一行id=’QM_OwnerInfo_ModifyIcon’,通过判断是否存在这个元素来判断是否有权限访问好友空间

# 判断是否有查看的权限
    try:
        driver.find_element_by_id('QM_OwnerInfo_ModifyIcon')
         b = True
    except:
        b = False

爬取好友多页说说(不包括评论信息和点赞信息)的数据

#爬取内容
        driver.switch_to.frame('app_canvas_frame')
        next_page = 'page'
        page = 1
        try:
            #爬取全部说说
            while next_page:
                print('正在抓取第%d页面内容······' % page)
                contents = driver.find_elements_by_css_selector('.content')  
                times = driver.find_elements_by_css_selector('
                .c_tx.c_tx3.goDetail')               
                for content, stime in zip(contents, times):
                    data = {
                        'qq':qq,
                        'time': stime.text,
                        'shuos': content.text
                    }
                    #插入到数据库
                    qzone.insert_one(data)
                    # print(data)
                next_page = driver.find_element_by_link_text('下一页')#文本定位
                next_page.click()
                time.sleep(3)#等待页面加载
                driver.implicitly_wait(3)
                page = page + 1
        except:
            print('抓取到%d页面结束' % page)

爬取之前要获取好友列表,这里介绍上节说的第二种获取好友列表的方法,打开qq邮箱,点击左侧的通讯录,在右侧的界面中qq好友下面将好友添加到通讯录中,在工具中选择导出联系人,导出格式csv,这样我们就得到了导出的联系人的表格。
处理表格:

#path 为传入的通讯录的文件的路径
def get_friends_list(path):
    fp = open(path)
    reader = csv.DictReader(fp)
    for row in reader:
        qq = row['电子邮件'].split('@')[0]
        #存入数据库
        QQ.insert_one({'qq':qq})
    fp.close()

完整版:

from selenium import webdriver
import time
from multiprocessing import Pool
import pymongo
import csv

client = pymongo.MongoClient('localhost',27017)
mydb = client['Qzone']
#好友列表
QQ = mydb['QQ']
#说说信息
qzone = mydb['qzone']

#打开csv文件
def get_friends_list(path):
    fp = open(path)
    reader = csv.DictReader(fp)
    for row in reader:
        qq = row['电子邮件'].split('@')[0]
        QQ.insert_one({'qq':qq})
    fp.close()

def get_info(qq):
    driver.get('https://user.qzone.qq.com/{}/311'.format(qq))
    driver.implicitly_wait(10)
    #登录
    try:
        driver.find_element_by_id('login_div')
        a = True
    except:
        a = False

    if a == True:
        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('账号')
        driver.find_element_by_id('p').clear()
        driver.find_element_by_id('p').send_keys('密码')
        driver.find_element_by_id('login_button').click()
        time.sleep(3)
    driver.implicitly_wait(3)
    # 判断是否有查看的权限
    try:
        driver.find_element_by_id('QM_OwnerInfo_ModifyIcon')
        b = True
    except:
        b = False
        print('无法访问%s的空间,需要权限 '% qq)

    if b == True:
        #爬取内容
        driver.switch_to.frame('app_canvas_frame')
        next_page = 'page'
        page = 1
        try:
            #爬取全部说说
            while next_page:
                print('正在抓取第%d页面内容······' % page)
                contents = driver.find_elements_by_css_selector('.content')
                times = driver.find_elements_by_css_selector('.c_tx.c_tx3.goDetail')
                for content, stime in zip(contents, times):
                    data = {
                        'qq':qq,
                        'time': stime.text,
                        'shuos': content.text
                    }
                    qzone.insert_one(data)
                    # print(data)
                next_page = driver.find_element_by_link_text('下一页')#文本定位
                next_page.click()
                time.sleep(3)#等待页面加载
                driver.implicitly_wait(3)
                page = page + 1
        except:
            print('抓取到%d页面结束' % page)



# driver = webdriver.PhantomJS()
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(chrome_options=chrome_options)

driver.maximize_window() #窗口最大化

if __name__ == '__main__':
    get_friends_list('传入导出的联系人的路径')
    friends = [item['qq'] for item in QQ.find()]
    pool = Pool(processes=4)
    pool.map(get_info,friends)

下篇再续