Python單線程爬取QQ空間說(shuō)說(shuō)存入MySQL并生成詞云(超詳細(xì)講解设江,踩坑經(jīng)歷)

看了網(wǎng)上的許多博客,基本上都是一個(gè)樣攘轩,基本的知識(shí)也沒(méi)詳細(xì)解釋?zhuān)疫@次也想跟大家仔細(xì)分析一下叉存,自己還是要有一定爬蟲(chóng)基礎(chǔ),本人技術(shù)有限度帮,如果本文哪有錯(cuò)誤或不夠準(zhǔn)確的地方歼捏,還望大牛們指點(diǎn)ヾ(????)?"


一稿存、環(huán)境配置:

  • Python 3.6

  • selenium (<font color=#FF0000>注意:</font>先配置好自己瀏覽器的驅(qū)動(dòng),下載地址看下面)

  • pymysql

  • re

  • requests

點(diǎn)擊下載chrome的---->Chrome_webdriver

點(diǎn)擊下載Firefox的---->Firefox_webdriver

點(diǎn)擊下載IE的---->IE_webdriver

先來(lái)張效果圖看看效果

image

二瞳秽、思路:

作為一個(gè)菜雞學(xué)了一點(diǎn)爬蟲(chóng)瓣履,就想做一個(gè)好友的說(shuō)說(shuō)分析,最開(kāi)始我以為這個(gè)爬蟲(chóng)很簡(jiǎn)單幾十行就可以搞定练俐,然而忽略了一些東西袖迎。。腺晾。瓢棒。(先賣(mài)個(gè)關(guān)子)


先說(shuō)說(shuō)整個(gè)過(guò)程的想法:

image

看起來(lái)是不是很簡(jiǎn)單?(手動(dòng)dog)那現(xiàn)在我們就來(lái)按步驟操作一下

1.找到包含好友的QQ信息的url(這里也有兩種方法)

  • 法一

先點(diǎn)開(kāi)好友這一欄,通過(guò)親密度的排行來(lái)獲取丘喻,這里我們點(diǎn)開(kāi)F12,選中Network

一般這種信息都在XHR或者JS類(lèi)型里面念颈,大家可以在這里面找找泉粉,通過(guò)一會(huì)的尋找我們就發(fā)現(xiàn)friend_ship開(kāi)頭這xhr里面的items_list就包含了好友的QQ號(hào)和姓名,但是此方法獲取的qq不全榴芳,只是大部分的qq

kFEYMq.png
kFE4Fe.png
  • 法二:

點(diǎn)擊頁(yè)面最上面的設(shè)置按鈕嗡靡,滑動(dòng)可見(jiàn)好友,通過(guò)js的結(jié)果分析窟感,隨著下滑請(qǐng)求的url的頁(yè)數(shù)都在變化讨彼,我們只要每次修改下頁(yè)數(shù)的參數(shù)就可以獲取所有好友的QQ,這個(gè)方法可以獲取所有的好友的qq柿祈,但對(duì)于qq好友很少的朋友來(lái)說(shuō)哈误,此方法不適用

image
image
image

2.找到包含好友的說(shuō)說(shuō)的url

我們先隨便點(diǎn)進(jìn)一個(gè)好友的空間進(jìn)行分析

image

點(diǎn)進(jìn)去過(guò)后,我們F12 進(jìn)行分析躏嚎,發(fā)現(xiàn)一頁(yè)最多存20條說(shuō)說(shuō)蜜自,以此我們可以通過(guò)說(shuō)說(shuō)總數(shù)(re提取)來(lái)算出一共有多少頁(yè)卢佣,然后通過(guò)構(gòu)造url來(lái)獲取

image

通過(guò)以上的分析過(guò)后我們開(kāi)始獲取url:

我們先看看獲取qq的第一種方法的url:

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

我們分析一下這里面每次登錄都在變的參數(shù)

  • g_tk (空間加密算法)

  • qzonetoken (空間源碼里面的參數(shù))

那這兩個(gè)參數(shù)我們要怎么獲取呢重荠?為什么每次登錄這兩個(gè)參數(shù)的都在變呢?

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

在看看session的基本概念

快速查看 cookies 的方法:按F12進(jìn)入瀏覽器的開(kāi)發(fā)者模式——console——在命令行輸入javascript:alert(document.cookie)虚茶,再回車(chē)即可看見(jiàn)

所以我們登錄過(guò)后戈鲁,每次都訪問(wèn)url的時(shí)候都要保持著參數(shù)不變,也就是說(shuō)cookie不能變

每次都要是<font color=##FF0000>同一個(gè)cookie</font>(就相當(dāng)于每次都是以你的身份保持著登錄狀態(tài)去訪問(wèn)他人空間)嘹叫,否則就會(huì)出現(xiàn)以下情況↓

image

理解好以上的幾個(gè)問(wèn)題過(guò)后婆殿,問(wèn)題就解決了一大部分了

接著我們分析g_tk參數(shù),在自己qq空間主頁(yè) F12 點(diǎn)JS類(lèi)型文件待笑,找到以下文件,查看Preview部分鸣皂,分析一下其中的代碼

image
image

<del>其實(shí)這個(gè)程序的意思,</del> 還是直接上代碼吧


def get_tk(cookie):

    hashes = 5381     

    for i in cookie['p_skey']:    #提取cookie中p_skey每個(gè)字母

        hashes += (hashes << 5) + ord(i)  #加密過(guò)程,ord()將 字符轉(zhuǎn)化為ASCII碼

                                  # << 二進(jìn)制 左移運(yùn)算 左移幾位就相當(dāng)于乘以2的幾次方

    return hashes & 2147483647  #二進(jìn)制 與運(yùn)算

    # 比如  2&3 轉(zhuǎn)為二進(jìn)制  10&11

#  都是1結(jié)果為1,否則為0 

#    所以二進(jìn)制算出來(lái)是  10  返回2

#  還不懂的朋友寞缝,還是自行Baidu吧

隨著我們分析第二個(gè)參數(shù)qzonetoken

這個(gè)參數(shù)很好獲取癌压,在我們空間主頁(yè)右鍵查看網(wǎng)頁(yè)源代碼,Ctrl+F查找下可以找到,之后我們可以通過(guò)正則提取

image

ok荆陆,理解了上面的全部滩届,基本就完成了80%了,接下來(lái)我們開(kāi)始代碼實(shí)現(xiàn)

三被啼、代碼實(shí)現(xiàn):

先導(dǎo)入第三方庫(kù)


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模擬瀏覽器實(shí)現(xiàn)

def login():

    driver = webdriver.Chrome()  # 傳入瀏覽器對(duì)象

    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')))# 顯式等待 找到賬號(hào)密碼登錄按鈕

    time.sleep(1)

    input.click()    # 交互點(diǎn)擊

    driver.find_element_by_id('u').clear()  #清空里面的內(nèi)容

    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重新定位回來(lái),不然后續(xù)會(huì)出錯(cuò)

    return driver

  1. 通過(guò)傳回來(lái)的driver對(duì)象獲取網(wǎng)頁(yè)源代碼和cookies

通過(guò)源代碼獲取qzonetoken參數(shù)


def get_qzonetoken(html):

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

    res = re.findall(paa, html)[0]  # 因?yàn)榉祷氐氖橇斜硇问脚ㄌ澹灾蝗〉谝粋€(gè)元素

    return res

注意:driver.get_cookies()獲取的cookies是散的泡挺,所以要進(jìn)行以下操作:


def get_tk(cookie):  #加密過(guò)程

    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']  #將對(duì)應(yīng)表達(dá)聯(lián)系起來(lái)

        #  上一步不懂的可以把 cookies的值輸出來(lái)看一下

    g_tk = get_tk(cookie)

3.將cookies傳給requests,以保證都是在登錄狀態(tài)(<font color=#FF0000>最關(guān)鍵</font>)


def back_session(driver):

    mysession = requests.session()  #  建立一個(gè)session對(duì)話

    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)

    # 將字典轉(zhuǎn)化為cookiejar形式

    mysession.headers = headers  # 請(qǐng)求頭,防止反爬

    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)  #開(kāi)啟自動(dòng)提交 不然每次執(zhí)行

def save_mysql(say, stime, QQ, connection):  #這里我存入說(shuō)說(shuō)命浴、說(shuō)說(shuō)時(shí)間娄猫、qq號(hào)

    stime = str(stime)

    content = str(say)

    QQ = str(QQ)

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

    connection.query(sql)

#  數(shù)據(jù)庫(kù)建表的時(shí)候  一定要把字符集改成utf8

看看效果圖,爬了40多分鐘生闲,四萬(wàn)多條數(shù)據(jù)媳溺,有點(diǎn)<del>小慢。碍讯。悬蔽。</del>,很慢捉兴。大家可以嘗試下多線程爬取

image

完成以上步驟之后整個(gè)框架就都搭好了蝎困,其余數(shù)據(jù)的提取大家就先自己完成了吧(本文最后會(huì)給出GitHub地址),也希望大家看思路過(guò)后倍啥,自己操作难衰,不僅僅是copy、paste and run

導(dǎo)出某個(gè)好友的數(shù)據(jù)庫(kù)逗栽,用Notepad++過(guò)濾一些數(shù)據(jù)后盖袭,通過(guò)詞云分析


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')  # 打開(kāi)圖片

img_array = np.array(img)  # 將圖片裝換為數(shù)組

stopword = ['xa0']  # 設(shè)置停止詞,也就是你不想顯示的詞彼宠,這里這個(gè)詞是我前期處理沒(méi)處理好鳄虱,你可以刪掉他看看他的作用

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')  # 保存圖片

最后我么就分析到以下圖片,字越大說(shuō)明出現(xiàn)次數(shù)最多

image

最后貼上我的代碼鏈接 https://github.com/Leaderzhangyi/QQspider 希望大家能夠共同改進(jìn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凭峡,一起剝皮案震驚了整個(gè)濱河市拙已,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摧冀,老刑警劉巖倍踪,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件系宫,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡建车,警方通過(guò)查閱死者的電腦和手機(jī)扩借,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缤至,“玉大人潮罪,你說(shuō)我怎么就攤上這事×斐猓” “怎么了嫉到?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)月洛。 經(jīng)常有香客問(wèn)我何恶,道長(zhǎng),這世上最難降的妖魔是什么嚼黔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任导而,我火速辦了婚禮,結(jié)果婚禮上隔崎,老公的妹妹穿的比我還像新娘。我一直安慰自己韵丑,他們只是感情好爵卒,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著撵彻,像睡著了一般钓株。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上陌僵,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天轴合,我揣著相機(jī)與錄音,去河邊找鬼碗短。 笑死受葛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的偎谁。 我是一名探鬼主播总滩,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼巡雨!你這毒婦竟也來(lái)了闰渔?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤铐望,失蹤者是張志新(化名)和其女友劉穎冈涧,沒(méi)想到半個(gè)月后茂附,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡督弓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年营曼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咽筋。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡溶推,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奸攻,到底是詐尸還是另有隱情蒜危,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布睹耐,位于F島的核電站辐赞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏硝训。R本人自食惡果不足惜响委,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窖梁。 院中可真熱鬧赘风,春花似錦、人聲如沸纵刘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)假哎。三九已至瞬捕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間舵抹,已是汗流浹背肪虎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惧蛹,地道東北人扇救。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像香嗓,于是被迫代替她去往敵國(guó)和親爵政。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容