概述
最近開始混v2ex,v2ex發主題、回複都要收錢,發帖收錢還跟字數相關,之前不知道這些,發個文章内容太多,kao,沒錢了!
雖然主題有人回複會收到錢,但是也沒人回複啊,也不知道v2ex大佬們喜歡什麼内容!
幸好v2ex有個登入領币任務,每天還可以攢點錢,但是有些時候會忘啊,怎麼辦?…
嗯,程式員嘛,偷懶的辦法多…這就開始分析接口,自動領币!
然後呢,發個主題,總想看看有沒有大佬關注和回複,然後就時不時打開浏覽器,去重新整理一下頁面。
就跟大部分用windows的人一樣,回到桌面不右鍵+E(重新整理)一下,就感覺人生好像少了什麼東西(我好像是重症患者,用ubuntu也要找一下重新整理桌面)!
這種情況是不是病啊?!
然後呢,重新整理很浪費時間诶,有人回複,看着還算開心嘛,但也沒人回複,那不白浪費時間了嘛,還影響期待的小心情!
是以呢,還得加上自動消息提醒功能!
廢話完畢,開始幹活!
工具:
1. chrome/firefox
2. f12,network
3. python:requests、re
登入
開始分析登入接口。打開chrome,f12,進入登入頁面。隻需要輸入名字和密碼,沒有驗證碼,真好!
通路的連結是:
https://www.v2ex.com/signin
然後随便輸入什麼名字和密碼,點選登入,肯定失敗,頁面有提示。再看網絡請求資料:
POST https://www.v2ex.com/signin
Host: www.v2ex.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
//發送資料
6b79e5fdb638c190396648c486c313dca73ad9f6e4e122fafc356e54522eedc4:"111111111111111" //name
bb4419eb55aef4106a853ce9f4642d5d58ac021f4e1fef29a230e2352da74802:"11111111111" //password
once:"95083"
next:"/"
//登入錯誤
<div class="box">
<div class="header"><a href="/">V2EX</a> <span class="chevron"> › </span> 登入 <li class="fa fa-lock"></li></div>
<div class="problem">請解決以下問題然後再送出:<ul><li>使用者名和密碼無法比對</li></ul></div>
...
</div>
這個請求關鍵點:
- POST請求,url是
https://www.v2ex.com/signin
- 發送資料有名字和明文密碼,以及兩個其他不明字段
- 請求是https,是以明文密碼不會暴露。
在仔細看發送的4個資料。
名字和密碼對應的字段都是一長串字元,猜想這個是變化的,每次重新整理登入頁面都不一樣,多次嘗試下确認該猜想!
如何擷取呢,肯定是在打開登入頁面時就會收到伺服器傳回的這兩個字元串的。在登入html内容中一翻,看到如下:
<div class="box">
<div class="header"><a href="/">V2EX</a> <span class="chevron"> › </span> 登入 <li class="fa fa-lock"></li></div>
<div class="cell">
<form method="post" action="/signin">
<table cellpadding="5" cellspacing="0" border="0" width="100%">
<tr>
<td width="120" align="right">使用者名</td>
<td width="auto" align="left"><input type="text" class="sl" name="804c76d3f1472cdd8721d16f21de446186f2bae893748542ffda39963ff293f4" value="111111111111111" autofocus="autofocus" autocorrect="off" spellcheck="false" autocapitalize="off" placeholder="使用者名或電子郵箱位址" /></td>
</tr>
<tr>
<td width="120" align="right">密碼</td>
<td width="auto" align="left"><input type="password" class="sl" name="359a3968b3b6f37b05fceed766bd8995090a4fd5cdc74ba0a8cd17b44d2bc86e" value="" autocorrect="off" spellcheck="false" autocapitalize="off" /></td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left"><input type="hidden" value="79599" name="once" /><input type="submit" class="super normal button" value="登入" /></td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left"><a href="/forgot">我忘記密碼了</a></td>
</tr>
</table>
<input type="hidden" value="/" name="next" />
</form>
</div>
</div>
名字對應字段是
<input type="text" class="sl" name="804c76d3f1472cdd8721d16f21de446186f2bae893748542ffda39963ff293f4"
,
密碼對應字段是
<input type="password" class="sl" name="359a3968b3b6f37b05fceed766bd8995090a4fd5cdc74ba0a8cd17b44d2bc86e"
,
可以通過正則擷取到字段名。
名字正則:
r'<input type="text" class="sl" name="([\d\w]*?)"'
密碼正則:
r'<input type="password" class="sl" name="([\d\w]*?)"'
也看到了其他兩個資料字段,
<input type="hidden" value="79599" name="once" />
和
<input type="hidden" value="/" name="next" />
。
once
對應的值每次都不一樣,
next
的值應該是固定的
/
,但是為了保險,都通過正則來擷取
r'<input type="hidden" value="([\d\w]+?)" name="once" />'
r'<input type="hidden" value="(.+?)" name="next" />'
好了,到此登入請求需要的東西都分析完了,然後就是模拟接口發送請求了。
忘了還有一點,傳回狀态的判斷。
前面看到登入錯誤的有提示資訊,為了更人性化,把這個資訊拿到吧。
//登入錯誤
<div class="box">
<div class="header"><a href="/">V2EX</a> <span class="chevron"> › </span> 登入 <li class="fa fa-lock"></li></div>
<div class="problem">請解決以下問題然後再送出:<ul><li>使用者名和密碼無法比對</li></ul></div>
擷取錯誤資訊正則是這樣:
r'<div class="problem">.+?<ul><li>(.*?)</li></ul></div>'
登入成功判斷待會兒再分析。
通過py發送模拟登陸請求,代碼如下:
payload = {
self.form_name:name,
self.form_pass:pwd,
'once': self.form_once,
'next': self.form_next
}
r = self.s.post(url, data=payload, headers=headers)
儲存了傳回資料一看,沒成功啊,還是未登入的首頁。
重新再浏覽器登入一下,仔細分析了一下。
發送了登入請求之後,登入成功之後,頁面自動跳轉到
https://www.v2ex.com
,有登入資訊了。
猜測對請求的頭部資料做了某些校驗。
看看請求的頭部資料,如下:
Host: www.v2ex.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) ...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 167
Referer: https://www.v2ex.com/signin
Connection: keep-alive
Upgrade-Insecure-Requests: 1
一般來說可能會對host,referer等字段檢查,加入嘗試一下。
headers = {
#'Host': 'www.v2ex.com',
#'origin':'https://www.v2ex.com',
'referer':'https://www.v2ex.com/signin',
}
成功登入,屏蔽其中一些字段,發現隻需要加入referer即可登入。
擷取登入成功狀态,可以看到登入成功後,會有使用者賬戶資訊,如下:
<a href="/member/anhkgg" class="top">anhkgg</a>
<a href="https://workspace.v2ex.com/" target="_blank" class="top">工作空間</a>
<a href="/notes" class="top">記事本</a> <a href="/t" class="top">時間軸</a> <a href="/settings" class="top">設定</a>
<a href="#;" onclick="if (confirm('确定要從 V2EX 登出?')) { location.href= '/signout?once=54090'; }" class="top">登出</a></td>
那麼隻需要搜尋是否存在
<a href="/member/anhkgg" target="_blank" rel="external nofollow"
即可。正規表達式是:
r'<a href="/member/.+?" target="_blank" rel="external nofollow" >'
。找到該内容表示登入成功。
退出
登入成功了,順便看一下退出的接口。抓包看一下,發現通路了如下連結:
https://www.v2ex.com/signout?once=
又見到once字段,值又是每次不同的。那麼也隻有動态擷取一下了。在前面登入成功的資訊中其實可以看到有退出接口的内容。
onclick="if (confirm('确定要從 V2EX 登出?')) { location.href= '/signout?once=54090'; }" class="top">登出</a></td>
通過正則擷取一下once:
r"location.href= '/signout\?once=([\d\w]+?)'"
,然後模拟退出。
url = 'https://www.v2ex.com/signout'
payload = { 'once': self.signout_once}
self.s.get(url, params=payload)
新評論
接着就看看我需要的功能了。
首先是擷取最新評論條數。找到對應html的内容,如下:
非常簡單,關鍵字notifications,正則一搜即可拿到。
r'<a href="/notifications" target="_blank" rel="external nofollow" .*?>(\d+?)(.*?)</a>'
不在細說。
為了能主動提醒我是否有最新消息,登入成功後,沒10分鐘重新整理一下
https://www.v2ex.com
,再擷取評論條數即可。
有新評論就通知我。
領取每日獎勵
嗯,錢的事還是挺重要的。
首頁右側,每天會出現領取今日獎勵的按鈕,什麼時候出現不知道(過了淩晨12點?),點選後跳轉到領取頁面,再點選領取按鈕就拿到錢了!
第一步,拿到領取頁面的連結。看下面,是固定的,終于省了一點點事。
通過下面的代碼跳到領取頁面。
url = 'https://www.v2ex.com/mission/daily'
r= self.s.get(url)
然後看看領取按鈕對應的連結,又見once!so,連結不是固定的了。
<div class="cell">
<h1>每日登入獎勵 20170818</h1>
<input type="button" class="super normal button" value="領取 X 銅币" onclick="location.href = '/mission/daily/redeem?once=48881';" />
</div>
動态擷取once對應的值,正則跟退出接口很像:
r"'/mission/daily/redeem\?once=([\d\w]+?)'"
然後模拟請求領取獎勵。
url = 'https://www.v2ex.com/mission/daily/redeem'
payload = { 'once': once}
r = self.s.get(url, params=payload)
總結
好了,到這裡分析就完成了。分析内容非常詳細,然後也貼了些關鍵代碼,是以完整代碼就暫時不提供了!
v2ex登入通過變化的名字和密碼字段,以及once的值,增加了一定的分析成本,但是總的來說,還是沒什麼難度!擋不了多少人!
其他自動回複啊,最新主題啊…等等,各位看官自行腦洞了!
pylogin系列還将繼續,盡請關注!
安利一下公衆号:漢客兒
部落格原文:https://anhkgg.github.io/pylogin-v2ex-login-analyze/