|
0×00 背景
赤い封筒はどんな感じですか? 彼の兄の息子フエルは「お金はほぼ同等だ」と語りました。 兄と娘の道雲は言った。「風のせいで叔母ほど良くないよ。」 「みんな背景はわかってるよ。新年で、赤い封筒が空中に飛び交う日なんだ。 たまたま2日前にPythonを習得して、もっとワクワクしていたので、Weiboの紅封通しを何度も勉強しました。なぜAlipayの赤封じゃなくてWeiboの紅封じゃないのか、私はウェブしか理解できないからです。もしエネルギーがあれば、将来的にモグラ叩きのアルゴリズムも勉強するかもしれません。 私はPython初心者なので、このプログラムはPythonを学んでから書いた3番目のプログラムでもあります。ですから、コードに穴があったら直接突っ込まないでください。焦点はアイデアにあります。もし穴があれば、直接突っ込まないでください。IEはデフォルトブラウザに設定する顔を持っています。私はクズ記事を書くのも許容範囲です...... 私はPython 2.7を使っていますが、Python 2とPython 3には大きな違いがあると言われています。
0×01のアイデア 言葉で説明するのが面倒だったので、スケッチを描いてみて、みんなに理解できるはずだと思いました。
まず最初に、昔ながらのルールですが、まずは役立つとわからないけれど、絶対に使えないライブラリを紹介しましょう。 [mw_shl_code=java,true]import re、urllib import urllib2、querylibraryをインポート、base64をインポート、binascii、os import、json、sys、import cPickle、as p import rsa[/mw_shl_code]その後、後で使う必要がある他の変数を宣言します。
[mw_shl_code=java,true]reload(sys)sys.setdefaultencoding('utf-8&') #将字符编码置为utf-8luckyList=[] #红包列表lowest=10 #能忍受红包领奖记录最低为多少[/mw_shl_code]ここではPythonにはデフォルトで含まれていないRSAライブラリを使用しています。 インストールが必要です :https://pypi.python.org/pypi/rsa/
ダウンロードしたらインストールを実行し setpy.py、その後開発作業を始められます。
0×02 微博ログイン 赤い封筒を取る動作はログイン後に行う必要があるため、ログイン機能が必要で、ログインはキーではなく、キーはクッキーの保存です。ここではクッキーライブラリの協力が必要です。 [mw_shl_code=java,true]cj = クッキーライブラリ。 CookieJar()opener = urllib2.build_opener(urllib2. HTTPCookieProcessor(cj))urllib2.install_opener(opener)[/mw_shl_code] こうすることで、openerを使うすべてのネットワーク操作がクッキーの状態を処理します。詳しくはわかりませんが、とても使いやすいです。 次に、2つのモジュールをカプセル化する必要があります。1つはデータ取得モジュールで、単にデータを取得するために使われ、もう1つはPOSTデータに使われます。 [mw_shl_code=java,true]def getData(url) : try: req = urllib2. Request(url) result = opener.open(req) text = result.read() text=text.decode("utf-8").encode("gbk",'ignore') テキストを返しますが例外、e: print u' request exception, URL: '+URL print e def postData(URL,data,header) : try: data = urllib.urlencode(data) req = urllib2. Request(url, data, header) result = opener.open(req) text = result.read() テキストを返しますが例外を除きます。e: print u'Request exception, url: '+url[/mw_shl_code] これら2つのモジュールで、データ取得とPOSTができます。getDataがデコードしてからエンコードする理由の一つは、Win7ではデバッグ時に出力がいつも乱れてしまうため、エンコーディング処理を追加しましたが、これらは目的ではなく、下記のログイン機能がWeiboログインの核です。 [mw_shl_code=java,true]def login(nick, pwd): print u"----------login----------" print "----------......----------" prelogin_url= 'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=%s&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.15)&_=1400822309846' % nick preLogin = getData(prelogin_url) servertime = re.findall('"servertime":(.+?', preLogin)[0] pubkey = re.findall('"pubkey":"(.+?)",', preLogin)[0] rsakv = re.findall('"rsakv":"(.+?)",' , preLogin)[0] nonce = re.findall('"nonce":"(.+?)",', preLogin)[0] #print bytearray('xxxx','utf-8') su = base64.b64encode(urllib.quote(nick)) rsaPublickey= int(pubkey,16) key = rsa. PublicKey(rsaPublickey,65537) message = str(servertime) +'\t' + str(nonce) + '\n' + str(pwd) sp = binascii.b2a_hex(rsa.encrypt(message,key)) header = {'User-Agent' : 'Mozilla/5.0 (互換性があります; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'} param = { 'entry': 'weibo', 'gateway': '1', 'from': '', 'savestate': '7', 'userticket': '1', 'ssosimplelogin': '1', 'vsnf': '1', 'vsnval': '', 'su': su, 'service': 'miniblog', 'servertime': servertime, 'nonce': nonce、'pwencode': 'rsa2', 'sp': sp, 'encoding': 'UTF-8', 'URL': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', 'returntype': 'META', 'rsakv' : rsakv, } s = postData('http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)',param,header) try: urll = re.findall("locatio remove n.replace\(\'(.+?)\'\); " , s)[0] login=getData(urll) print u"--------- ログイン成功! -------「print」----------......----------「例外を除く、e: print u」---------ログイン失敗! -------" print "----------......----------" exit(0)[/mw_shl_code]このパラメータや暗号化アルゴリズムはインターネットからコピーしたもので、よく理解できません。おそらく、まずタイムスタンプと公開鍵を要求し、その後RSA暗号化し、最後に処理処理を処理してSinaのログインインターフェースに提出するというものです。Sinaからログインに成功すると、Weiboアドレスが返されます。ログイン状態が完全に有効になるために、それをリクエストする必要があります。 ログインに成功した後、その後のリクエストは現在のユーザーのクッキーを含みます。
0×03 指定赤封筒抽選 Weiboに無事ログインできた後、まずはブラウザで試すために赤い封筒を見つけるのが待ちきれません。 ついに赤い封筒ボタンのあるページを見つけ、F12はデバッガを呼び出してデータパケットの要求を確認しました。
リクエストのアドレスは http://huodong.weibo.com/aj_hongbao/getlucky で、主に2つのパラメータがあります。1つはouid、つまりURLに見られる赤い封筒IDです。もう1つはWeiboに共有するかどうかを決めるshareパラメータです。そして、何のためか分からない_tもあります。 理論的には、このURLに3つのパラメータを提出すれば赤い封筒の抽出は完了できますが、実際にパラメータを提出すると、サーバーが魔法のように次のような文字列を返してくれます。 [mw_shl_code=java、真]{"code":303403,"msg":"すみませんが、このページへのアクセス権限はありません","data":[]}[/mw_shl_code] 今は慌てないでください。私の長年のウェブ開発経験によると、相手のプログラマーはリファラーを判断すべきです。非常にシンプルで、過去のリクエストのすべてのヘッダーをコピーするだけです。 [mw_shl_code=java,true]def getLucky(id): #抽奖程序 print u"--- draw red envelope from:"+str(id)+"---" print "----------......----------" checkValue(id)==False: #不符合条件、これは return later の関数です luckyUrl="http://huodong.weibo.com/aj_hongbao/getlucky" param={ 'ouid':id, 'share':0, '_t':0 } header= { 'Cache-Control':'no-cache', 'Content-Type':'application/x-www-form-urlencoded', 'Origin':'http://huodong.weibo.com', 'Pragma':'no-cache', 'Referer': 'http://huodong.weibo.com/hongbao/'+str(id), 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML、ゲッコのように) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36', 'X-Requested-With':'XMLHttpRequest' } res = postData(luckyUrl,param, mw_shl_codeこの場合、理論上は問題ありませんが、実際には問題はありません。 宝くじアクションが完了した後、状況を判断する必要があります。返されたresはjson文字列で、コード100000が成功、90114なら今日の宝くじの上限値であり、他の値も失敗となります。 [mw_shl_code=java,true]hbRes=json.loads(res)if hbRes["code"]=='901114': #今天红包已经抢完 print u"--------- has passed time---------" print "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"]) exit(0)elif hbRes["code"]=='100000':#成功 print u"---------Wishing you prosperity---------" print "----------......----------" log('success',str(id)+'---'+res) exit(0) hbRes["data"] と hbRes["data"]["title"]: print hbRes["data"]["title"] print "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"])else: print u"---------Request error---------" print "----------......----------" log('lucky', str(id)+'---'+res)[/mw_shl_code]。ここでlogは私がカスタマイズした関数で、ログの記録に使われます: [mw_shl_code=java,true]def log(type,text):fp = open(type+'.txt','a') FP.write(text) FP.write('\r\n') FP.Close()[/mw_shl_code]
|