Python: re.sub()第二個參數


起源:

問題源於解析kissanime.io這個網站。
為反扒抑或是防止ddos攻擊,此視頻頁面,初進去會有個5秒延遲並提交一表單驗證。而其表單驗證,為下面一段html代碼:

  <form id="challenge-form" action="/cdn-cgi/l/chk_jschl" method="get">
    <input type="hidden" name="jschl_vc" value="d5f32a77955a830758982219a37f1124"/>
    <input type="hidden" name="pass" value="1500949414.776-fpKIjtEKZR"/>
    <input type="hidden" id="jschl-answer" name="jschl_answer"/>
  </form>

求jschl-answer值 ,用了一段js代碼,此段js代碼為隨機生成,如下:

    var s,t,o,p,b,r,e,a,k,i,n,g,f, nyqPwxi={"KxtkYgr":+((!+[]+!![]+!![]+[])+(+!![]))};
    t = document.createElement('div');
    t.innerHTML="<a href='/'>x</a>";
    t = t.firstChild.href;r = t.match(/https?:\/\//)[0];
    t = t.substr(r.length); t = t.substr(0,t.length-1);
    a = document.getElementById('jschl-answer');
    f = document.getElementById('challenge-form');
    ;nyqPwxi.KxtkYgr*=+((!+[]+!![]+[])+(!+[]+!![]+!![]));nyqPwxi.KxtkYgr+=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]));nyqPwxi.KxtkYgr+=+((!+[]+!![]+!![]+[])+(+!![]));nyqPwxi.KxtkYgr*=+((+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]));nyqPwxi.KxtkYgr+=!+[]+!![]+!![];nyqPwxi.KxtkYgr+=+((!+[]+!![]+!![]+[])+(+!![]));a.value = parseInt(nyqPwxi.KxtkYgr, 10) + t.length; '; 121'
    f.submit();

沒有格式化,比較凌亂。
由其可見,jschl-answer值域,是通過一系列公式運算所得。運行js得到其值,就可以模擬表單提交,通過驗證

 

1、獲取需要的js代碼段

不外乎用到re這個東西。參照一個開源項目,通過以下python代碼,實現js代碼提取:

    try:
        js = re.search(r"setTimeout\(function\(\){\s+(var "
            "s,t,o,p,b,r,e,a,k,i,n,g,f.+?\r?\n[\s\S]+?a\.value =.+?)\r?\n", body).group(1)
    except Exception:
        raise ValueError("Unable to identify Cloudflare IUAM Javascript on website.")

    js = re.sub(r"a\.value = (parseInt\(.+?\)).+", r"\1", js)
    js = re.sub(r"\s{3,}[a-z](?: = |\.).+", "", js)
    js = re.sub(r"[\n\\']", "", js)
    if "parseInt" not in js:
        raise ValueError("Error parsing Cloudflare IUAM Javascript challenge.")

    js = js.replace('parseInt', ';return parseInt')
    js = 'function answer(){%s}' % js

中間這一段:

js = re.sub(r"a\.value = (parseInt\(.+?\)).+", r"\1", js)

被蒙到了!對re.sub運用尚未純熟,此寫法,一開始忽住了我,隨搜集其做研究學習,倒也有些收獲。

 

2、re.sub(pattern, repl, string, count=0, flags=0)

這是它的原型,網上對此式解說文章,多不勝數。對第二個參數,repl,上述用法,述者寥寥
但其功能,是以第一個參數,pattern中第一個組中值,替換pattern所匹配的字串,其格式為\number,編號從1開始第應第1組,以此類推,功能與\g<number>相同,為簡潔寫法。

比如:

s = '2017-01-22'
s = re.sub('(\d{4})-(\d{2})-(\d{2})', r'\2-\3-\1', s)
print s  # 01-22-2017

r'\g<0>'能匹配pattern所適配的字串,而r'\0'卻不能,這是測試中發現其不同處。

若在patter中有\number寫法,則是要匹配其中分組,如下寫法:

inputStr = "hello crifan, nihao crifan";
replacedStr = re.sub(r"hello (\w+), nihao \1", "crifanli", inputStr);
print "replacedStr=", replacedStr; #crifanli

它匹配了inuptStr整個字串,此字串,被crifanli完整替換之。

 

3、其它寫法

repl除了字串外,它還可以是函數,以對匹配到的組,做其它操作。

照搬一個例子:

def replace_digit(m):
    ss = u'〇一二三四五六七八九'
    index = int(m.group())
    return ss[index]

s = u'1990年3月27日'
result = re.sub(u'\d', replace_digit, s, count=4)

print result # 一九九〇年3月27日

 

參考資料:

http://www.jianshu.com/p/731efbd6029b

https://docs.python.org/2/library/re.html#re.sub


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM