覺得微博手動點贊太過麻煩?
其實自動點贊的實現并不困難!
本篇會有Cookie、session和token方面的知識,不太了解的可以先看下
web前端cookie session及token會話機制詳解
我們先通過前兩個小節大概了解一下我們Python登錄微博的原理,然后第三小節就會跟大家介紹微博自動點贊的代碼。
一、實現登陸微博功能
首先進入微博頁面后按F12打開開發者工具,將如圖的按鈕點擊后,在瀏覽器中手動登陸一次,在Network 標簽的XHR類型中找到Login請求標簽,在Form data下我們可以看到username(用戶名)和password(密碼),并知道了請求方式是POST,請求的參數有很多我們直接照搬就是。
網頁截圖
這時,可能學過一些爬蟲的同學便會直接上手寫出如上雷同的代碼,但發現出不來結果
會報錯的代碼
import requests headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" } login_data = { "username": "你的用戶名", "password": "你的密碼", "savestate": "1", "r": "https://m.weibo.cn/?jumpfrom=weibocom", "ec": "0", "pagerefer": "https://m.weibo.cn/login?backURL=https%253A%252F%252Fm.weibo.cn%252F%253Fjumpfrom%253Dweibocom", "entry": "mweibo", "wentry": "", "loginfrom": "", "client_id": "", "code": "", "qq": "", "mainpageflag": "1", "hff": "", "hfp": "", } login_req = requests.post("https://passport.weibo.cn/sso/login", data=login_data, headers=headers) print(login_req.status_code)
這是因為有些網站并不只是按照"user-agent"判斷用戶的正常訪問的。那我們還需點開Request Headers(請求頭)檢查可能還有什么字段會用來判斷用戶正常訪問
一般 referer(請求來源頁面)、origin(誰發起的請求)、host(主機名及端口號) 字段也常被用于反爬蟲,當我們的爬蟲無法正常獲取數據時,我們可以將請求頭里的這些字段照搬進去試試。經過驗證,微博網頁是以referer 來判斷是否是用戶正常訪問。最后我們還可以把Cookie放進代碼里,這樣就不用在代碼里輸入賬號密碼了。
要注意Cookie并不是永久有效的,若發現自動登錄失敗,可以重新上網頁把新的Cookie復制下來更換
完整的代碼如下
import requests headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", "referer": "https://passport.weibo.cn/signin/login? entry=mweibo&res=wel&wm=3349&r=https%3A%2F%2Fm.weibo.cn%2F%3Fjumpfrom%3Dweibocom", "cookie": "你的cookie" } login_data = { "savestate": "1", "r": "https://m.weibo.cn/?jumpfrom=weibocom", "ec": "0", "pagerefer": "https://m.weibo.cn/login?backURL=https%253A%252F%252Fm.weibo.cn%252F%253Fjumpfrom%253Dweibocom", "entry": "mweibo", "wentry": "", "loginfrom": "", "client_id": "", "code": "", "qq": "", "mainpageflag": "1", "hff": "", "hfp": "", } login_req = requests.post("https://passport.weibo.cn/sso/login", data=login_data, headers=headers) print(login_req.status_code) #輸出200則代表登錄成功
二、實現發送微博
既然都登陸微博了,我們先試試能不能順便發微博吧
同樣的,在微博編輯頁面點擊F12進入開發者工具,我們先試試發送一個微博,Network標簽會出現什么新的內容吧
網頁截圖
當微博界面點擊發送之后,Network標簽就會出現update的請求,點進去可以看到,請求地址是https://m.weibo.cn/api/statuses/update,請求方法是 POST。參數有兩個一個是content 也就是發送的微博內容,另一個是st,這里的st通過幾次的檢驗,猜測應該是網站的反爬蟲措施。這里獲得st的方法是通過同為Network標簽下的config請求,里面存放了st值,我們將 JSON 格式的字符串轉換為字典,然后取到 st 的值
方法
config_req = session.get("https://m.weibo.cn/api/config") config = config_req.json() st = config["data"]["st"] print(st) #每隔一段時間st值會改變
登錄和發送微博的完整代碼如
import requests headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", "referer": "https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=https%3A%2F%2Fm.weibo.cn%2F%3Fjumpfrom%3Dweibocom", "cookie": "你的cookie" } login_data = { "savestate": "1", "r": "https://m.weibo.cn/?jumpfrom=weibocom", "ec": "0", "pagerefer": "https://m.weibo.cn/login?backURL=https%253A%252F%252Fm.weibo.cn%252F%253Fjumpfrom%253Dweibocom", "entry": "mweibo", "wentry": "", "loginfrom": "", "client_id": "", "code": "", "qq": "", "mainpageflag": "1", "hff": "", "hfp": "", } # 使用 session來保留登錄狀態 session = requests.Session() session.headers.update(headers) login_req = session.post("https://passport.weibo.cn/sso/login", data=login_data) # 獲取 st 請求 config_req = session.get("https://m.weibo.cn/api/config") config = config_req.json() st = config["data"]["st"] compose_data = { "content": input("請輸入發送的內容:"),, "st": st } compose_req = session.post("https://m.weibo.cn/api/statuses/update", data=compose_data) print(compose_req.json()) # 輸出:{"ok": 1, "data": 省略部分內容...}
調整結構后的代碼(功能一樣)如
import requests class WeiboSpider: def __init__(self): self.session = requests.Session() self.headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", "referer": "https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=https%3A%2F%2Fm.weibo.cn%2F%3Fjumpfrom%3Dweibocom", "cookie": "你的Cookie" } self.session.headers.update(self.headers) def login(self): login_data = { "savestate": "1", "r": "https://m.weibo.cn/?jumpfrom=weibocom", "ec": "0", "pagerefer": "https://m.weibo.cn/login?backURL=https%253A%252F%252Fm.weibo.cn%252F%253Fjumpfrom%253Dweibocom", "entry": "mweibo", "wentry": "", "loginfrom": "", "client_id": "", "code": "", "qq": "", "mainpageflag": "1", "hff": "", "hfp": "", } self.session.post("https://passport.weibo.cn/sso/login", data=login_data) def get_st(self): config_req = self.session.get("https://m.weibo.cn/api/config") config = config_req.json() st = config["data"]["st"] return st def compose(self, content): compose_data = { "content": content, "st": self.get_st() } compose_req = self.session.post("https://m.weibo.cn/api/statuses/update", data=compose_data) print(compose_req.json()) def send(self, content): self.login() self.compose(content) weibo = WeiboSpider() weibo.send(input("請輸入發送的內容:"))
三、實現微博自動點贊
完整的代碼
import requests class WeiboSpider: def __init__(self): self.session = requests.Session() self.headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", "referer": "https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=https%3A%2F%2Fm.weibo.cn%2F%3Fjumpfrom%3Dweibocom", "cookie": "你的cookie" } self.session.headers.update(self.headers) def login(self): login_data = { "savestate": "1", "r": "https://m.weibo.cn/?jumpfrom=weibocom", "ec": "0", "pagerefer": "https://m.weibo.cn/login?backURL=https%253A%252F%252Fm.weibo.cn%252F%253Fjumpfrom%253Dweibocom", "entry": "mweibo", "wentry": "", "loginfrom": "", "client_id": "", "code": "", "qq": "", "mainpageflag": "1", "hff": "", "hfp": "", } self.session.post("https://passport.weibo.cn/sso/login", data=login_data) def get_st(self): config_req = self.session.get("https://m.weibo.cn/api/config") config = config_req.json() st = config["data"]["st"] return st def compose(self, content): compose_data = { "content": content, "st": self.get_st() } compose_req = self.session.post("https://m.weibo.cn/api/statuses/update", data=compose_data) print(compose_req.json()) def send(self, content): self.login() self.compose(content) # 獲取微博列表 def get_weibo_list(self): params = { "type": "uid", "value": "2139359753", "containerid": "1076032139359753" } weibo_list_req = self.session.get("https://m.weibo.cn/api/container/getIndex", params=params) weibo_list_data = weibo_list_req.json() weibo_list = weibo_list_data["data"]["cards"] return weibo_list # 點贊微博 def vote_up(self, id): vote_up_data = { "id": id, # 要點贊的微博 id "attitude": "heart", "st": self.get_st() } vote_up_req = self.session.post("https://m.weibo.cn/api/attitudes/create", data=vote_up_data) json = vote_up_req.json() print(json["msg"]) # 批量點贊微博 def vote_up_all(self): self.login() weibo_list = self.get_weibo_list() for i in weibo_list: # card_type 為 9 是正常微博 if i["card_type"] == 9: self.vote_up(i["mblog"]["id"]) weibo = WeiboSpider() weibo.vote_up_all()
謝謝大家,Python的分享就到此為止,以后如果有好玩的Python程序,我還會繼續向大家分享的,希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/huisoul/article/details/116008126