Python单线程爬取QQ空间说说存入MySQL并生成词云(超详细讲解,踩坑经历)

看了网上的许多博客,基本上都是一个样,基本的知识也没详细解释,我这次也想跟大家仔细分析一下,自己还是要有一定爬虫基础,本人技术有限,如果本文哪有错误或不够准确的地方,还望大牛们指点ヾ(๑╹◡╹)ノ"


一、环境配置:

  • Python 3.6

  • selenium (<font color=#FF0000>注意:</font>先配置好自己浏览器的驱动,下载地址看下面)

  • pymysql

  • re

  • requests

点击下载chrome的---->Chrome_webdriver

点击下载Firefox的---->Firefox_webdriver

点击下载IE的---->IE_webdriver

先来张效果图看看效果

image

二、思路:

作为一个菜鸡学了一点爬虫,就想做一个好友的说说分析,最开始我以为这个爬虫很简单几十行就可以搞定,然而忽略了一些东西。。。。(先卖个关子)


先说说整个过程的想法:

image

看起来是不是很简单?(手动dog)那现在我们就来按步骤操作一下

1.找到包含好友的QQ信息的url(这里也有两种方法)

  • 法一

先点开好友这一栏,通过亲密度的排行来获取,这里我们点开F12,选中Network

一般这种信息都在XHR或者JS类型里面,大家可以在这里面找找,通过一会的寻找我们就发现friend_ship开头这xhr里面的items_list就包含了好友的QQ号和姓名,但是此方法获取的qq不全,只是大部分的qq

kFEYMq.png
kFE4Fe.png
  • 法二:

点击页面最上面的设置按钮,滑动可见好友,通过js的结果分析,随着下滑请求的url的页数都在变化,我们只要每次修改下页数的参数就可以获取所有好友的QQ,这个方法可以获取所有的好友的qq,但对于qq好友很少的朋友来说,此方法不适用

image
image
image

2.找到包含好友的说说的url

我们先随便点进一个好友的空间进行分析

image

点进去过后,我们F12 进行分析,发现一页最多存20条说说,以此我们可以通过说说总数(re提取)来算出一共有多少页,然后通过构造url来获取

image

通过以上的分析过后我们开始获取url:

我们先看看获取qq的第一种方法的url:

https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/friend_ship_manager.cgi?uin=你的QQ号&do=1&rd=0.55484478707938&fupdate=1&clean=1&g_tk=1376935160&qzonetoken=6e4e0b063e3f00421d98df35b330c8bb2158bb8697e5dc7a85a65b379407706960f0b1c422f9a26879&g_tk=1376935160

我们分析一下这里面每次登录都在变的参数

  • g_tk (空间加密算法)

  • qzonetoken (空间源码里面的参数)

那这两个参数我们要怎么获取呢?为什么每次登录这两个参数的都在变呢?

我们首先先要了解一下---->cookie

在看看session的基本概念

快速查看 cookies 的方法:按F12进入浏览器的开发者模式——console——在命令行输入javascript:alert(document.cookie),再回车即可看见

所以我们登录过后,每次都访问url的时候都要保持着参数不变,也就是说cookie不能变

每次都要是<font color=##FF0000>同一个cookie</font>(就相当于每次都是以你的身份保持着登录状态去访问他人空间),否则就会出现以下情况↓

image

理解好以上的几个问题过后,问题就解决了一大部分了

接着我们分析g_tk参数,在自己qq空间主页 F12 点JS类型文件,找到以下文件,查看Preview部分,分析一下其中的代码

image
image

<del>其实这个程序的意思,</del> 还是直接上代码吧


def get_tk(cookie):

    hashes = 5381     

    for i in cookie['p_skey']:    #提取cookie中p_skey每个字母

        hashes += (hashes << 5) + ord(i)  #加密过程,ord()将 字符转化为ASCII码

                                  # << 二进制 左移运算 左移几位就相当于乘以2的几次方

    return hashes & 2147483647  #二进制 与运算

    # 比如  2&3 转为二进制  10&11

#  都是1结果为1,否则为0 

#    所以二进制算出来是  10  返回2

#  还不懂的朋友,还是自行Baidu吧

随着我们分析第二个参数qzonetoken

这个参数很好获取,在我们空间主页右键查看网页源代码,Ctrl+F查找下可以找到,之后我们可以通过正则提取

image

ok,理解了上面的全部,基本就完成了80%了,接下来我们开始代码实现

三、代码实现:

先导入第三方库


import re, requests

import time, pymysql

from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

  1. 首先是登录,我们这里用selenium模拟浏览器实现

def login():

    driver = webdriver.Chrome()  # 传入浏览器对象

    wait = WebDriverWait(driver, 5)  # 显式等待

    driver.get('https://qzone.qq.com/')

    driver.switch_to_frame('login_frame')      #切换到登录窗口

    input = wait.until(EC.presence_of_element_located((By.ID, 'switcher_plogin')))# 显式等待 找到账号密码登录按钮

    time.sleep(1)

    input.click()    # 交互点击

    driver.find_element_by_id('u').clear()  #清空里面的内容

    driver.find_element_by_id('u').send_keys('your_qq')  #传入你的QQ

    time.sleep(3)

    driver.find_element_by_id('p').clear() 

    driver.find_element_by_id('p').send_keys('your_password')  #传入你的密码

    button = driver.find_element_by_id('login_button')  #找到登录按钮

    time.sleep(3) 

    button.click()

    time.sleep(1)

    driver.switch_to.default_content()  # 将frame重新定位回来,不然后续会出错

    return driver

  1. 通过传回来的driver对象获取网页源代码和cookies

通过源代码获取qzonetoken参数


def get_qzonetoken(html):

    paa = re.compile(r'window\.g_qzonetoken = \(function\(\)\{ try\{return "(.*?)";\} catch\(e\)', re.S)

    res = re.findall(paa, html)[0]  # 因为返回的是列表形式,所以只取第一个元素

    return res

注意:driver.get_cookies()获取的cookies是散的,所以要进行以下操作:


def get_tk(cookie):  #加密过程

    hashes = 5381

    for i in cookie['p_skey']:

        hashes += (hashes << 5) + ord(i)

    return hashes & 2147483647



  cookies = driver.get_cookies()

for item in cookies:

        cookie[item['name']] = item['value']  #将对应表达联系起来

        #  上一步不懂的可以把 cookies的值输出来看一下

    g_tk = get_tk(cookie)

3.将cookies传给requests,以保证都是在登录状态(<font color=#FF0000>最关键</font>)


def back_session(driver):

    mysession = requests.session()  #  建立一个session对话

    cookies = driver.get_cookies()

    cookie = {}

    for item in cookies:

        cookie[item['name']] = item['value']

    headers = {

        'authority': 'user.qzone.qq.com',

        'referer': 'https://qzone.qq.com/',

        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',

        'accept-encoding': 'gzip, deflate, br',

        'accept-language': 'zh-CN,zh;q=0.9',

        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36'

    }

    c = requests.utils.cookiejar_from_dict(cookie, cookiejar=None, overwrite=True)

    # 将字典转化为cookiejar形式

    mysession.headers = headers  # 请求头,防止反爬

    mysession.cookies.update(c)  # 更新cookies

    return mysession  # 返回带cookies的requests

  1. 存入MySQL

connection = pymysql.connect(host='your_host', port=3306, user='你的账户', passwd='你的密码', db='your_database')

connection.autocommit(True)  #开启自动提交 不然每次执行

def save_mysql(say, stime, QQ, connection):  #这里我存入说说、说说时间、qq号

    stime = str(stime)

    content = str(say)

    QQ = str(QQ)

    sql = 'insert into qq values ("{}","{}","{}")'.format(content, stime, QQ)

    connection.query(sql)

#  数据库建表的时候  一定要把字符集改成utf8

看看效果图,爬了40多分钟,四万多条数据,有点<del>小慢。。。</del>,很慢。大家可以尝试下多线程爬取

image

完成以上步骤之后整个框架就都搭好了,其余数据的提取大家就先自己完成了吧(本文最后会给出GitHub地址),也希望大家看思路过后,自己操作,不仅仅是copy、paste and run

导出某个好友的数据库,用Notepad++过滤一些数据后,通过词云分析


import jieba

from matplotlib import pyplot as plt

from wordcloud import WordCloud

from PIL import Image

import numpy as np

path = r'your_data.text_path'

font = r'C:\Windows\Fonts\simkai.TTF'  #  字体path

text = (open('C:/Users/hp/Desktop/233.txt', 'r', encoding='utf-8')).read() # 如果是中文的话encoding换成utf8

cut = jieba.cut(text)  # 分词

string = ' '.join(cut)

print(len(string))

img = Image.open('your_photo_path')  # 打开图片

img_array = np.array(img)  # 将图片装换为数组

stopword = ['xa0']  # 设置停止词,也就是你不想显示的词,这里这个词是我前期处理没处理好,你可以删掉他看看他的作用

wc = WordCloud(

    scale=4,  #清晰度

    background_color='white',  #背景颜色

    max_words=400,    #最多单词

    width=1000,

    height=800,

    mask=img_array,

    font_path=font,

    stopwords=stopword  # 停用词

)

wc.generate_from_text(string)  # 绘制图片

plt.imshow(wc)

plt.axis('off')

plt.figure()

#plt.show()  # 显示图片

wc.to_file('F:/3.png')  # 保存图片

最后我么就分析到以下图片,字越大说明出现次数最多

image

最后贴上我的代码链接 https://github.com/Leaderzhangyi/QQspider 希望大家能够共同改进

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容