看了網(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)張效果圖看看效果
二瞳秽、思路:
作為一個(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ò)程的想法:
看起來(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
- 法二:
點(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ō)哈误,此方法不適用
2.找到包含好友的說(shuō)說(shuō)的url
我們先隨便點(diǎn)進(jìn)一個(gè)好友的空間進(jìn)行分析
點(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)獲取
通過(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)以下情況↓
理解好以上的幾個(gè)問(wèn)題過(guò)后婆殿,問(wèn)題就解決了一大部分了
接著我們分析g_tk參數(shù),在自己qq空間主頁(yè) F12 點(diǎn)JS類(lèi)型文件待笑,找到以下文件,查看Preview部分鸣皂,分析一下其中的代碼
<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ò)正則提取
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
- 首先是登錄帜消,我們這里用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
- 通過(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
- 存入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>,很慢捉兴。大家可以嘗試下多線程爬取
完成以上步驟之后整個(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ù)最多
最后貼上我的代碼鏈接 https://github.com/Leaderzhangyi/QQspider 希望大家能夠共同改進(jìn)