天天看點

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" 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系列還将繼續,盡請關注!

安利一下公衆号:漢客兒

pylogin系列之V2EX自動領币消息提醒概述登入退出新評論領取每日獎勵總結

部落格原文:https://anhkgg.github.io/pylogin-v2ex-login-analyze/