Python爬蟲之記錄一次下載驗證碼的嘗試

  好久沒有寫過爬蟲的文章了,今天在嘗試著做驗證碼相關的研究時,遇到了驗證碼的收集問題。
  一般,驗證碼的載入都有著比較複雜的演算法和加密在裡邊,但是筆者今天碰到的驗證碼卻比較幸運,有跡可循。在此,給出本爬蟲的相關記錄。
  注意,文章和程式碼中均不會給出相關的真實網站的資訊,避免不道德的行為。
  首先,讓我們來看一看該驗證碼的頁面,如下:
驗證碼示例頁面
如果我們嘗試著查看該驗證碼載入時的源程式碼,會發現源碼如下:
驗證碼載入的源碼
我們可以發現,該驗證碼的載入機制其實並不複雜,只是在網址後面跟了一個時間戳,而這個時間戳,是由JavaScript中的方法產生的,函數內容為new Date().getTime()
  知道了驗證碼背後載入的原理,那麼我們不難通過Python來實現驗證碼的下載。
  可惜的是,上述JS函數產生的時間戳是13位數字,而Python的time.time()方法產生的時間戳為浮點數,小數點前10位,小數點後6位。那麼,我們如果來產生符合上述JS函數產生的時間戳呢?
  一個簡單的想法是,我們讓Python來調用JS。真的可以嗎?幸運的是,前人已經提我們做好了這個工作,有個神奇的Python第三方模組,叫做PyExecJS。顧名思義,這個模組就是用來執行JS程式碼的。
  該模組的源碼中給出了一個例子,我們可以嘗試下,程式碼如下:

# -*- coding: utf-8 -*-

import execjs

print(execjs.eval("'red yellow blue'.split(' ')"))

ctx = execjs.compile("""
         function add(x, y) {
             return x + y;
         }
        """)

print(ctx.call("add", 1, 2))

輸出結果如下:

['red', 'yellow', 'blue']
3

  OK,有了上面的例子,我們就知道如何使用該模組了,我們可以輕鬆地寫出下面的程式碼來下載驗證碼了:

# -*- coding: utf-8 -*-

import execjs
import urllib.request

js_func = """
             function get_milliseconds(){
                 return new Date().getTime();
             }
          """

ctx = execjs.compile(js_func)
result = ctx.call("get_milliseconds")
print(len(str(result)))

# 注意,網址已經隱藏
url = "//***/captcha/?%s" % result

urllib.request.urlretrieve(url, "1.png")

下載的驗證碼如下:
下載的驗證碼圖片
  通過我們這次的嘗試,發現如下:

  • PyExecJS支援Python對JavaScript的操作,所以下次有機會,可以在Python中執行JS函數;
  • 驗證碼的載入演算法不宜簡單,要注意加密。

  本次分享到此結束,感謝大家的閱讀~