• 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.+?
    ?
    [sS]+?a.value =.+?)
    ?
    ", 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"[
    \']", "", 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所匹配的字串,其格式为 umber,编号从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''却不能,这是测试中发现其不同处。

    若在patter中有 umber写法,则是要匹配其中分组,如下写法:

    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

  • 相关阅读:
    今天还要去一次北仑
    重归漫漫长路
    双休日,累
    调整心情,迎接新的挑战
    多喝点水,对身体有好处
    丈人生病住院了
    WPF,DataGrid数据绑定
    AXIS2简介
    心事一件件的了掉,希望一切都能恢复到正常
    驾车是种乐趣,也是种累
  • 原文地址:https://www.cnblogs.com/crwy/p/7232943.html
Copyright © 2020-2023  润新知