|
0×00 Предистория
Какви са червените пликове? Синът на брат му, Хуер, каза: "Парите са почти сравними. Братът и дъщерята Дао Юн казаха: "Не е толкова добре, колкото на леля ми заради вятъра." "Всички разбират предисторията, това е Нова година и денят, когато червени пликове летят по цялото небе. Случи се така, че научих Python преди два дни и бях по-развълнуван, затова изучавах и изучавах пълзенето на червени пликове в Weibo, защо червени пликове в Weibo вместо червени пликове на Alipay, защото разбирам само уеб и ако имам енергия, може би в бъдеще ще изуча и алгоритъма whack-a-mole. Тъй като съм начинаещ в Python, тази програма е и третата програма, която написах след като научих Python, така че моля, не се питайте лично, ако има някаква пропускливост в кода, фокусът е върху идеята, ако има някаква празнина в идеята, моля, не я пипайте лично, виждате ли, IE има лице да се постави като стандартен браузър, а аз пиша статия за мръсни текстове също е приемлива...... Използвам Python 2.7 и се казва, че има голяма разлика между Python 2 и Python 3.
0×01 Идеи Бях твърде мързелив да го опиша с думи, затова нарисувах скица и всеки би трябвало да може да я разбере.
Първо, старото правило – първо въведете библиотека, за която не знаете, че е полезна, но не можете без: [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] След това обявете някои други променливи, които ще трябва да използвате по-късно:
[mw_shl_code=java,true]reload(sys)sys.setdefaultencoding('utf-8&') #将字符编码置为utf-8luckyList=[] #红包列表lowest=10 #能忍受红包领奖记录最低为多少[/mw_shl_code]Тук се използва rsa библиотека, която по подразбиране не е включена в Python. Трябва да го инсталирам :https://pypi.python.org/pypi/rsa/
След като го изтеглите, стартирайте setpy.py инсталация и тогава можем да започнем стъпките си за разработка.
0×02 Вход в Weibo Действието за вземане на червени пликове трябва да се извърши след влизане, затова трябва да има функция за вход, логинът не е ключът, ключът е запазването на бисквитките, тук е необходима сътрудничество с cookielib. [mw_shl_code=java,true]cj = cookielib. CookieJar()opener = urllib2.build_opener(urllib2. HTTPCookieProcessor(cj))urllib2.install_opener(opener)[/mw_shl_code] По този начин всички мрежови операции с opener ще обработват състоянието на бисквитките, макар че не знам много за това, но усещането е невероятно. След това трябва да капсулираме два модула – единият е модулът за събиране на данни, който се използва просто за ПОЛУЧАВАНЕ на данни, а другият за 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() return text с изключение на Exception, e: print u'Request exception, url: '+url[/mw_shl_code] С тези два модула можем да GET и POST данни, сред които причината getData да декодира и след това да кодира е, че при Win7 винаги съм обърквал изхода при дебъгване, затова добавих малко обработка на кодиране, но това не е основната функция, функцията за вход по-долу е ядрото на Weibo login. [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) съобщение = 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', 'sso simplelogin': '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" --------- входът не успя! -------" отпечатай "----------......----------" exit(0)[/mw_shl_code]Параметрите и алгоритмите за криптиране в това са копирани от Интернет, не разбирам много добре, вероятно е първо да се поиска времеви печат и публичен ключ, после RSA криптиране и накрая обработката и подаването в интерфейса за влизане в Sina, след успешно влизане от Sina, ще се върне Weibo адрес, трябва да го поискаш, за да може статусът на вход да влезе в сила напълно, След успешно влизане, следващите заявки ще носят текущата бисквитка на потребителя.
0×03 Чертеж с определен червен плик След като успешно влязох във Weibo, нямам търпение да намеря червен плик, за да го пробвам първо, разбира се, първо в браузъра. Накрая намерих страница с червен бутон за плик, F12 призова дебъгера, за да види какво иска пакетът с данни.
Можете да видите, че адресът на заявката е http://huodong.weibo.com/aj_hongbao/getlucky, има два основни параметъра – единият е ouid, тоест червеният плик id, който се вижда в URL адреса, другият параметър share определя дали да го споделя в Weibo, и има _t не знам за какво е. Добре, теоретично можете да завършите извличането на червени пликове, като подадете три параметъра на този URL, но когато реално изпратите параметрите, сървърът магически ще върне такъв низ: [mw_shl_code=java, вярно] {"code":303403,"msg":"Съжалявам, нямате разрешение за достъп до тази страница","data":[]}[/mw_shl_code] Не се паникьосвайте сега, според многогодишния ми опит в уеб разработката, програмистът на другата страна трябва да прецени реферера, много просто, копирайте всички заглавия на предишната заявка. [mw_shl_code=java,true]def getLucky(id): #抽奖程序 print u"--- нарисувам червен плик от:"+str(id)+"---" print "----------......----------" ако checkValue(id)==False: #不符合条件, това е функцията return по-късно 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, подобно на Gecko) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36', 'X-Requested-With':'XMLHttpRequest' } res = postData(luckyURL,param, header)[/mw_shl_code] В този случай теоретично няма проблем, но всъщност няма проблем. След като лотарийното действие приключи, трябва да преценим статуса, а върнатият res е json низ, при който кодът е 100000 е успешен, а ако е 90114, това е горната граница на днешната лотария, а другите стойности също са провалени, така че: [mw_shl_code=java,true]hbRes=json.loads(res)if hbRes["code"]=='901114': #今天红包已经抢完 print u"--------- е достигнал горната граница---------" print "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"]) exit(0)elif hbRes["code"]=='100000':#成功 print u"---------Пожелавам ти просперитет---------" 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]
|