zoukankan      html  css  js  c++  java
  • Content-Type

    EgのExcelHome上传附件:

    类MultipartEncoder:
     
    2参boundary的-及字母数字的数量同Content-Type的bdr,而postData中各键首行的boundary则在开头补了俩-:其__init__内有句self.boundary = '--{0}'.format(self.boundary_value)。
    postData中各键值对的结构:--boundary行、……key行、[文件流独有的Content-Type行]、空行、value行。列完各键值对,postData最后以--boundary--行结尾。
     
    默认方法.to_string(),能如F12界面所示的postData那样显示。上传的文件名不能有中文,如F12下看到的是filename="测.rar",mpe却会给处理为filename*=utf-8''%E6%B5%8B.rar而上传失败,故而要么文件名无中文,要么m.to_string()后再作替换。
    *********************分割线*********************
    import os,random,string,requests
    from fake_useragent import UserAgent as ua
    from requests_toolbelt import MultipartEncoder
    from tkinter.filedialog import askopenfilenames as ofn
     
    def data参数法(fileData):
        postData={'uid':uid,'hash':hash,'Filedata':fileData}
        boundary='-'*10+''.join(random.choices(string.ascii_letters+string.digits,k=30))
        m=MultipartEncoder(postData,boundary)
        headers['Content-Type']=m.content_type
        print(requests.post(url,m,headers=headers).text)
     
    def files参数法(fileData):
        #files参数的模式{k:(fileName,v,对应的Content-Type),},若v非文件流则(*)的首尾可为空
        #files={'uid':(None,uid),'hash':(None,hash),'Filedata':fileData}
        #r=requests.post(url,files=files,headers=headers)
        r=requests.post(url,{'uid':uid,'hash':hash},files={'Filedata':fileData},headers=headers)
        print(r.text)
     
    if __name__ == '__main__':
        url='http://club.excelhome.net/misc.php?mod=swfupload&fid=2&action=swfupload&operation=upload'
        headers={'User-Agent':ua().random}
        uid='24810??'   #本例postData中的uid,hash,Filedata为必需键;??为我的学号-1
        hash='8dfae1d86bfc714ec489e6518094d2b2'
        filesName=ofn(initialdir=os.path.dirname(__file__),title='选择上传的各文件,路径不能有中文')
        for fileName in filesName:
            with open(fileName,'rb') as f:
                fileData=(os.path.basename(fileName),f)  #末项'application/octet-stream'等CT的值可不写
                #data参数法(fileData)
                files参数法(fileData)
     
    出现7位数字为成功,到论坛如下的发帖界面,可看到"未使用的附件"的提示:
    http://club.excelhome.net/forum.php?mod=post&action=newthread&fid=2。
    ****************************************分割线****************************************
    Egの登录知呼:
     
    import requests,time,execjs,json,random,string
    from parsel import Selector
    from requests_toolbelt import MultipartEncoder
     
    def getData(username,password,captcha=''):
        client_id='c3cef7c66a1843f8b3a9e6a1e3160e20'
        timestamp=int(time.time()*1000)
        with open('D:/signature.js','r',encoding='utf8') as f:
            text=f.read()
        signature=execjs.compile(text).call('run',client_id,timestamp)
        data={'username':username,'password':password,'captcha':captcha,
              'client_id':client_id,'grant_type':'password','timestamp':str(timestamp),
            'source':'com.zhihu.web','signature':signature}
        return data
     
    def getHeaders():
        headers=originalHeaders
        response=Selector(s.get(indexUrl,headers=headers).text)
        jsons=response.css('div#data::attr(data-state)').extract_first()
        jsons=json.loads(jsons)['token']
        xudid,xsrf=jsons['xUDID'],jsons['xsrf']
        headers.update({'x-udid':xudid,'x-xsrftoken':xsrf,
            'Referer':indexUrl+'signup?next=%2F',
            'authorization':'oauth c3cef7c66a1843f8b3a9e6a1e3160e20'})
        return headers
     
    def checkCaptcha(headers,cn=True):
        captchaUrl=indexUrl+'api/v3/oauth/captcha?lang='+('cn' if cn else 'en')
        headers.pop('x-xsrftoken')
        s.get(captchaUrl,headers=headers)
     
    def login(username,password):
        headers=getHeaders()
        checkCaptcha(headers)   #无论拦路虎是否跳出,中途路过都得打个招呼
        postData=getData(username,password)
        boundary='-'*27+''.join(random.choices(string.digits,k=11))
        m=MultipartEncoder(postData,boundary)
        headers['Content-Type']=m.content_type
        s.post(indexUrl+'api/v3/oauth/sign_in',m,headers=headers)
        s.headers=originalHeaders
        response=s.get(indexUrl+'settings/profile').text
        print(response)
        if '个性域名'in response:
            print(response,'登录成功',sep=' ')
     
    if __name__=='__main__':
        s=requests.Session()
        indexUrl='https://www.zhihu.com/'
        originalHeaders={'User-Agent':'Mozilla/5.0 Firefox/57.0 Chrome/64.0'}
        username='+86'+'手机号'
        password='密码'
        login(username,password)
    *********************分割线*********************
    D:/signature.js:
     
    ………………截取自js文件的a函数及在同一个父函数块下的众兄弟函数………………
     
    function run(client_id,timestamp) {
        r = new a("SHA-1", "TEXT");
        r.setHMACKey("d1b964811afb40118a12068ff74a12f4", "TEXT");
        r.update('password');  //grantType:e,postData中已知grantType为'password'
        r.update(client_id);  //clientId:i.a,i.a同样讨巧取自postData的clientId,不再在js摸索
        r.update("com.zhihu.web");
        r.update(String(timestamp));
        return r.getHMAC("HEX")
    }
     
    js解析历程:
     
    ①:定位到postData参数signature的出处:function r(e,t){var n=Date.now(),r=new a.a("SHA-1","TEXT");return r.setHMACKey("d1b964811afb40118a12068ff74a12f4","TEXT"),r.update(e),r.update(i.a),r.update("com.zhihu.web"),r.update(String(n)),s({clientId:i.a,grantType:e,timestamp:n,source:"com.zhihu.web",signature:r.getHMAC("HEX")},t)}。 
     
    ②:测试发现末行的s({k:v,},t)并没对各键值对再做加工,可忽略s(*),然后改装为上文的run函数。形参t没被r引用故不管它,e没精力探索了,因其又是s({})的grantType的value,而比较几次抓包所得的401验证Session的postData,发现grantType是固定的,clientId也是,于是就取巧把它俩各自对应的e、i.a直接给出,用于r.update(*)。
     
    ③:r来自函数名a,并且用到了a的3个子函数setHMACKey、update、getHMAC。用便搜的EditPlus打开js文件:任搜个子函数,如搜function getHMAC或getHMAC=function或{key:"getHMAC",value:function(){。光标定位至此,再搜上一个function a或a=function或{key:"a",value:function(){,这样就找到a的开头,上文的js可不理了。把a函数头至js文件尾格式化下,格式化后光标移至文首搜^},即第1个出现在行首的},就是a函数的结尾。
     
    ④:把a的函数块及改装的run函数块贴到Console回车,最后执行run('hello',666),然而报错缺参数。看来只有a的函数块不行,于是范围先扩大为a的父函数块。本例a的上1行恰好就是其父的function头故不必搜头了,取父头至js文件尾再格式化,然后搜^},得a父的function块。取出父(*){…}的…函数正文,删除最后几句不明所以且惹错的void 0 !==(){…}.call()…,末尾的var那几行没用到也可不要,然后和run的function块、run('hello',666)先后在Console回车,出结果了。
  • 相关阅读:
    HTML表单
    CSS等高布局的6种方式
    HTML用户反馈表单
    HTML美化修饰<A>
    sql查询语句 --------一个表中的字段对应另外一个表中的两个字段的查询语句
    jq 表格添加删除行
    js 静止f1到f12 和屏蔽鼠标右键
    手机自适应页面的meta标签
    tp3.2 的验证码的使用
    php多线程抓取网页
  • 原文地址:https://www.cnblogs.com/scrooge/p/7693847.html
Copyright © 2011-2022 走看看