pylogin系列之V2EX自動領幣消息提醒

概述

最近開始混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">&nbsp;›&nbsp;</span> 登錄 &nbsp;<li class="fa fa-lock"></li></div>
    <div class="problem">請解決以下問題然後再提交:<ul><li>用戶名和密碼無法匹配</li></ul></div>

    ...

</div>

這個請求關鍵點:

  1. POST請求,url是https://www.v2ex.com/signin
  2. 發送數據有名字和明文密碼,以及兩個其他不明字段
  3. 請求是https,所以明文密碼不會暴露。

在仔細看發送的4個數據。
名字和密碼對應的字段都是一長串字符,猜想這個是變化的,每次刷新登錄頁面都不一樣,多次嘗試下確認該猜想!

如何獲取呢,肯定是在打開登錄頁面時就會收到服務器返回的這兩個字符串的。在登錄html內容中一翻,看到如下:

<div class="box">
    <div class="header"><a href="/">V2EX</a> <span class="chevron">&nbsp;›&nbsp;</span> 登錄 &nbsp;<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">&nbsp;›&nbsp;</span> 登錄 &nbsp;<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>&nbsp;&nbsp;&nbsp;
<a href="https://workspace.v2ex.com/" target="_blank" class="top">工作空間</a>&nbsp;&nbsp;&nbsp;
<a href="/notes" class="top">記事本</a>&nbsp;&nbsp;&nbsp;<a href="/t" class="top">時間軸</a>&nbsp;&nbsp;&nbsp;<a href="/settings" class="top">設置</a>&nbsp;&nbsp;&nbsp;
<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> &nbsp;<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系列還將繼續,盡請關注!

安利一下公衆號:漢客兒

這裏寫圖片描述

博客原文:https://anhkgg.github.io/pylogin-v2ex-login-analyze/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章