概述
最近開始混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"
即可。正則表達式是:r'<a href="/member/.+?">'
。找到該內容表示登錄成功。
退出
登錄成功了,順便看一下退出的接口。抓包看一下,發現訪問了如下鏈接:
https://www.v2ex.com/signout?once=71351
又見到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的內容,如下:
</a></div><a href="/notifications" class="fade">0 條未讀提醒</a></div>
非常簡單,關鍵字notifications,正則一搜即可拿到。
r'<a href="/notifications".*?>(\d+?)(.*?)</a>'
不在細說。
爲了能主動提醒我是否有最新消息,登錄成功後,沒10分鐘刷新一下https://www.v2ex.com
,再獲取評論條數即可。
有新評論就通知我。
領取每日獎勵
嗯,錢的事還是挺重要的。
首頁右側,每天會出現領取今日獎勵的按鈕,什麼時候出現不知道(過了凌晨12點?),點擊後跳轉到領取頁面,再點擊領取按鈕就拿到錢了!
第一步,拿到領取頁面的鏈接。看下面,是固定的,終於省了一點點事。
<div class="box"><div class="inner"><li class="fa fa-gift" style="color: #f90;"></li> <a href="/mission/daily">領取今日的登錄獎勵</a></div></div>
通過下面的代碼跳到領取頁面。
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系列還將繼續,盡請關注!
安利一下公衆號:漢客兒