目錄
一、前言
二、利用selenium模擬登陸獲取cookie并保存到本地
三、破解空間加密引數g_tk
四、在個人QQ空間好友欄獲取好友串列
五、獲取好友空間說說的json檔案,獲取姓名、說說內容、時間等資訊,存入資料庫
六、開啟多執行緒爬取
七、小結
很多人學習python,不知道從何學起,
很多人學習python,掌握了基本語法過后,不知道在哪里尋找案例上手,
很多已經做案例的人,卻不知道如何去學習更加高深的知識,
那么針對這三類人,我給大家提供一個好的學習平臺,免費領取視頻教程,電子書籍,以及課程的源代碼!??¤
QQ群:623406465
一、前言
玩了這么多年QQ,學了爬蟲當然要爬一下啦,肯定有大佬要說爬個QQ空間還要多執行緒嗎,人家只是剛看了多執行緒方面的知識想用一下啦*?(?′?`?)?*,第一次寫博客,希望有大佬能指出不足,
二、利用selenium模擬登陸獲取cookie并保存到本地
PS:很多朋友問我QQ空間現在用這個方法登錄有滑動驗證碼,但是論文+復試=繁忙,所以提供一個簡單的方法:
1、手動登錄自己的QQ空間,然后F12->Network,隨便點一個鏈接,手動復制下右邊Headers里邊的cookie
2、到python里運行下把cookie轉字典的代碼
cookie = '剛剛手動復制的cookie' # 字串cookie轉字典格式 cookie_dict = {} for i in cookie.split('; '): cookie_dict[i.split('=')[0]] = i.split('=')[1] print(cookie_dict)
效果如下:
3、獲取g_tk
用selenium打開https://i.qq.com/,可以選擇直接點擊已登陸的QQ頭像登陸或者選擇賬號密碼登陸,這里我采用賬號密碼登陸獲取cookie,需要注意的是登陸界面是在一個iframe里面,需要先切換到這個iframe里面然后才能點擊輸入賬號密碼以及登陸等操作,
這里我選擇把它保存到本地的txt檔案中,方便從檔案中直接讀取,具體獲取cookie的代碼如下:
from selenium import webdriver import time import json qq_number = '********' password = '********' login_url = 'https://i.qq.com/' driver = webdriver.Chrome() driver.get(login_url) #進入登陸的ifame driver.switch_to_frame('login_frame') driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click() time.sleep(1) driver.find_element_by_xpath('//*[@id="u"]').send_keys(qq_number) driver.find_element_by_xpath('//*[@id="p"]').send_keys(password) time.sleep(1) driver.find_element_by_xpath('//*[@id="login_button"]').click() time.sleep(1) cookie_list = driver.get_cookies() cookie_dict = {} for cookie in cookie_list: if 'name' in cookie and 'value' in cookie: cookie_dict[cookie['name']] = cookie['value'] with open('cookie_dict.txt', 'w') as f: json.dump(cookie_dict, f)
三、破解空間加密引數g_tk
我選擇使用QQ空間中好友欄獲取所有的好友串列,很容易就可以在network里邊發現有個好友串列的json格式的鏈接
這么舒服的嘛
不多嗶嗶,先發送個請求再說
headers有了啊,cookies也有了啊,403?!
這可咋整,俗話說遇事不決問百度,度娘的回答是引數中的g_tk是空間加密的一個引數,要想正確訪問就要把這個加密的值算出來,加密演算法在一個js中,
打開這個檔案看看,哇,怎么是一片奇奇怪怪的代碼,點一下Sources 面板下方的 pretty print 按鈕{}就可以把JavaScript的代碼格式化了,然后Ctrl+F找一下這個g_tk,發現他的值是QZFL.pluginsDefine.getACSRFToken()函式回傳的結果,再次Ctrl+F找到了這個函式的位置,
QZFL.pluginsDefine.getACSRFToken()函式獲取cookie中的p_sky的值,QZFL.pluginsDefine.getACSRFToken._DJB()函式將這個值通過與5381位運算算來算去得到一個值,這個值就是我們要的g_tk,將這段代碼改成我們要用的python代碼:
def get_g_tk(): p_skey = cookie_dict['p_skey'] h = 5381 for i in p_skey: h += (h << 5) + ord(i) g_tk = h & 2147483647 print('g_tk', g_tk) return g_tk
四、在個人QQ空間好友欄獲取好友串列
搞定了g_tk,接下來我們就只需要進剛才所說的空間好友欄頁面將所有的好友的QQ號抓下來,經過多次刪減引數,得到相關引數只有三個data = https://www.cnblogs.com/sn8888/archive/2020/10/23/{'uin': 1525943131, 'do': 1, 'g_tk': g_tk},用urllib.parse.urlencode(data)將引數轉成我們常見的url后面綴了一長串&&&的形式與原始鏈接拼接,然后就可以帶上cookies發送請求獲取json資料,小做處理得到好友QQ號串列:
def get_friends_uin(g_tk): yurl = 'https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/friend_ship_manager.cgi?' data = { 'uin': 1525943131, 'do': 1, 'g_tk': g_tk } url = yurl + urllib.parse.urlencode(data) res=requests.get(url, headers = headers, cookies = cookie_dict) r = res.text.split('(')[1].split(')')[0] friends_list=json.loads(r)['data']['items_list'] friends_uin=[] for f in friends_list: friends_uin.append(f['uin']) return friends_uin
五、獲取好友空間說說的json檔案,獲取姓名、說說內容、時間等資訊,存入資料庫
點進好友空間,點擊說說,我們在network里可以看到有這樣一個鏈接:
雙擊打開,我們會發現這是好友發的說說的json資料,有json資料就很好辦呀,刪減引數發現控制說說翻頁的引數是pos,每一頁最多20條,pos從0開始,每翻一頁增加20,構造鏈接,發送請求,獲取資料,小做處理,得到內容時間等資訊,設計資料庫,這里需要注意的是QQ號最好用bigint型別,不然有可能會超出int型別的最大范圍,content的字符集選用utf8mb4,因為QQ上Emoji表情或者某些特殊字符是4個位元組,MySQL的utf8編碼最多三個位元組:
還有幾個細節:好友的說說中有可能會有單引號、斜杠、反斜杠等奇奇怪怪的符號存在,會報錯,因此在存之前對content做pymysql.escape_string(content)的處理,escape_string函式會自動幫我們轉義這些特殊字符;好友如果設定了拒絕訪問,一定要拿小本本記下來!
具體代碼如下:
def get_dynamic(uin): print(uin) conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="123456", db='my_sql', charset='utf8mb4') cursor = conn.cursor() yurl = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?' pos = 0 while True: data = { 'uin': uin, 'pos':pos, 'num':20, 'replynum':100, 'callback':'_preloadCallback', 'code_version':1, 'format':'jsonp', 'need_private_comment':1, 'g_tk': g_tk } url = yurl + urllib.parse.urlencode(data) res=requests.get(url,headers = headers, cookies = cookie_dict) r = re.findall('\((.*)\)',res.text)[0] dynamic = json.loads(r) pos += 20 if 'msglist' in dynamic: msglist=dynamic['msglist'] if msglist: for m in msglist: name=m['name'] content=pymysql.escape_string(m['content']) created_time=m['created_time'] standard_time=time.localtime(created_time) standard_time = time.strftime("%Y-%m-%d %H:%M:%S", standard_time) sql = "insert into qzone_spider(qq_number, name, created_time, content) values (%d, '%s', '%s', '%s')" data = (uin, name, standard_time, content) try: cursor.execute(sql % data) except Exception as e: print(e) conn.commit() else: print("沒有更多的說說了╮(︶﹏︶)╭") break else: print("好友空間沒有對我開放(??ˇ_ˇ??:)") access_denied.append(uin) break
六、開啟多執行緒爬取
多執行緒的理解我認為就是一個人要干很多個人的活,為了加快速度,沒辦法嘍╮(╯_╰)╭
#設定執行緒池容量,創建執行緒池 pool_size = 10 pool = threadpool.ThreadPool(pool_size) #創建作業請求 reqs = threadpool.makeRequests(get_dynamic, friends_uin) #將作業請求放入佇列 [pool.putRequest(req) for req in reqs] #for req in requests: # pool.putRequest(req) pool.wait()
200位好友,一共四萬七千多條資料數,速度蠻快,效果如下:
其中居然有21位好友的空間拒絕對我開放!太讓人心痛了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/187354.html
標籤:其他
