|
0×00 Context
Cum sunt plicurile roșii? Fiul fratelui său, Huer, a spus: "Banii sunt aproape comparabili. Fratele și fiica Dao Yun au spus: "Nu e la fel de bun ca mătușa mea din cauza vântului." "Toată lumea înțelege fundalul, e Anul Nou și e ziua când plicurile roșii zboară peste tot pe cer. S-a întâmplat să învăț Python acum două zile și am fost mai entuziasmat, așa că am studiat și studiat crawling în plicurile roșii Weibo, de ce plicurile roșii Weibo în loc de plicurile roșii Alipay, pentru că înțeleg doar Web-ul, iar dacă am energie, poate voi studia și algoritmul whack-a-mole în viitor. Pentru că sunt începător în Python, acest program este și al treilea pe care l-am scris după ce am învățat Python, așa că vă rog să nu vă băgați personal dacă există vreo groapă în cod, accentul este pe idee, ei bine, dacă există vreo groapă în idee, vă rog să nu o puneți în persoană, vedeți IE are fața să se seteze ca browser implicit, scrierea unui articol slab este de asemenea acceptabil...... Eu folosesc Python 2.7 și se spune că există o diferență mare între Python 2 și Python 3.
0×01 Idei Am fost prea leneș să o descriu în cuvinte, așa că am desenat o schiță, iar toată lumea ar trebui să o poată înțelege.
În primul rând, vechea regulă: introdu mai întâi o bibliotecă pentru care nu știi că este utilă, dar nu te poți lipsi de ea: [mw_shl_code=java,true]import re import urllib import urllib2 import cookielib import base64 import binascii import OS import json import sys import cPickle as p import rsa[/mw_shl_code] Apoi declară și alte variabile pe care va trebui să le folosești mai târziu:
[mw_shl_code=java,true]reload(sys)sys.setdefaultencoding('utf-8&') #将字符编码置为utf-8luckyList=[] #红包列表lowest=10 #能忍受红包领奖记录最低为多少[/mw_shl_code]Aici se folosește o bibliotecă rsa, care nu este inclusă implicit în Python. Trebuie să-l instalez :https://pypi.python.org/pypi/rsa/
După ce îl descarcăm, rulăm setpy.py instalarea și apoi putem începe pașii de dezvoltare.
0×02 Autentificare Weibo Acțiunea de a lua plicurile roșii trebuie realizată după autentificare, deci trebuie să existe o funcție de autentificare, autentificarea nu este cheia, cheia este păstrarea cookie-urilor, aici este necesară cooperarea cookielib. [mw_shl_code=java,true]cj = cookielib. CookieJar()opener = urllib2.build_opener(urllib2. HTTPCookieProcessor(cj))urllib2.install_opener(opener)[/mw_shl_code] Astfel, toate operațiunile de rețea care folosesc opener-ul vor gestiona starea cookie-urilor, deși nu știu prea multe despre asta, dar se simte uimitor. Apoi, trebuie să încapsulăm două module, unul este modulul de achiziție a datelor, care este folosit pur și simplu pentru a obține date, iar celălalt este folosit pentru a POST date. [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') returnează text cu excepția excepției, 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() returnează text cu excepția Exception, e: print u'Request exception, url: '+url[/mw_shl_code] Cu aceste două module, putem GET și POST date, printre care motivul pentru care getData decodează și apoi encodează este că în Win7 am distorsionat mereu ieșirea la depanare, așa că am adăugat niște procesări de codificare, acestea nu sunt scopul, funcția de autentificare de mai jos este nucleul login-ului pe 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) cheie = rsa. PublicKey(rsaPublickey,65537) mesaj = str(servertime) +'\t' + str(nonce) + '\n' + str(pwd) sp = binascii.b2a_hex(rsa.encrypt(message,key)) antet = {'User-Agent' : 'Mozilla/5.0 (compatibil; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'} param = { 'intrare': 'weibo', 'gateway': '1', 'from': '', 'savestate': '7', 'userticket': '1', 'ssosimpleloging': '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"--------- Autentificare reușită! ------- "print" ----------......---------- "except Exception, e: print u" --------- logarea a eșuat! -------" print "----------......----------" exit(0)[/mw_shl_code]Parametrii și algoritmii de criptare din acest sistem sunt copiați de pe Internet, nu înțeleg prea bine, probabil este să ceri mai întâi un timestamp și o cheie publică, apoi criptarea RSA și în final procesarea procesării și trimiterea către interfața de autentificare Sina, după ce te-ai autentificat cu succes din Sina, va returna o adresă Weibo, trebuie să o soliciti, astfel încât starea de autentificare să poată avea efect complet, După autentificarea reușită, cererile ulterioare vor purta cookie-ul utilizatorului actual.
0×03 Desenul desemnat pentru plic roșu După ce m-am logat cu succes pe Weibo, abia aștept să găsesc un plic roșu pentru a încerca mai întâi, desigur, mai întâi în browser. În cele din urmă, am găsit o pagină cu un buton roșu de plic, F12 a chemat depanorul să vadă ce solicită pachetul de date.
Poți vedea că adresa cererii este http://huodong.weibo.com/aj_hongbao/getlucky, există doi parametri principali: unul este ouid, adică ID-ul plicului roșu, care poate fi văzut în URL, celălalt parametru de partajare determină dacă să fie partajat pe Weibo, și există un _t nu știu la ce folosește. Bine, teoretic poți finaliza extragerea plicurilor roșii trimițând trei parametri către acest URL, dar când trimiți efectiv parametrii, vei observa că serverul îți va returna magic un astfel de șir: [mw_shl_code=java,true] {"code":303403,"msg":"Ne pare rău, nu aveți permisiunea de a accesa această pagină","data":[]}[/mw_shl_code] Nu intrați în panică acum, conform multor ani de experiență în dezvoltare web, programatorul celeilalte părți ar trebui să judece referința, foarte simplu, să copieze toate anteturile cererii anterioare. [mw_shl_code=java,true]def getLucky(id): #抽奖程序 print u"--- desenează plicul roșu din:"+str(id)+"---" print "----------......----------" if checkValue(id)==False: #不符合条件, aceasta este funcția return mai târziu luckyUrl="http://huodong.weibo.com/aj_hongbao/getlucky" param={ 'ouid':id, 'share':0, '_t':0 } antet= { '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, ca Gecko) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36', 'X-Requested-With':'XMLHttpRequest' } res = postData(luckyUrl,param, antet)[/mw_shl_code] În acest caz, nu există o problemă teoretică, dar de fapt nu există nicio problemă. După ce acțiunea loteriei este finalizată, trebuie să judecăm statusul, iar res-ul returnat este un șir json, unde codul este 100000 este reușit, iar dacă este 90114, este limita superioară a loteriei actuale, iar celelalte valori sunt de asemenea eșuate, deci: [mw_shl_code=java,true]hbRes=json.loads(res)if hbRes["code"]=='901114': #今天红包已经抢完 print u"--------- a atins limita superioară---------" print "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"]) exit(0)elif hbRes["code"]=='100000':#成功 print u"---------Îți doresc prosperitate---------" print "----------......----------" log('success',str(id)+'---'+res) exit(0) dacă hbRes["data"] și 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], unde log este și o funcție pe care o personalizez, folosită pentru a înregistra logs: [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]
|