|
0×00 Contexte
À quoi ressemblent les enveloppes rouges ? Le fils de son frère, Huer, a déclaré : « L’argent est presque comparable. Le frère et la fille Dao Yun ont dit : « Ce n’est pas aussi bon que ma tante à cause du vent. » « Tout le monde comprend le contexte, c’est le Nouvel An, et c’est le jour où des enveloppes rouges volent partout dans le ciel. Il se trouve que j’ai appris Python il y a deux jours, et j’étais plus enthousiaste, alors j’ai étudié et étudié le crawling des enveloppes rouges Weibo, pourquoi les enveloppes rouges Weibo au lieu d’Alipay, car je ne comprends que le Web, et si j’en ai l’énergie, je pourrais aussi étudier l’algorithme du « toque-taupe » à l’avenir. Comme je suis débutant en Python, ce programme est aussi le troisième que j’ai écrit après avoir appris Python, donc s’il vous plaît, ne vous posez pas en personne s’il y a un gouffre dans le code, l’accent est mis sur l’idée, eh bien, s’il y a un gouffre dans l’idée, merci de ne pas le toucher en personne, vous voyez, IE a le pouvoir de se définir comme navigateur par défaut, écrire un article de mauvaise qualité est aussi acceptable...... J’utilise Python 2.7, et il est dit qu’il y a une grande différence entre Python 2 et Python 3.
0×01 Idées J’étais trop paresseux pour le décrire avec des mots, alors j’ai dessiné un croquis, et tout le monde devrait pouvoir le comprendre.
Tout d’abord, l’ancienne règle : introduisez d’abord une bibliothèque dont vous ne savez pas qu’elle est utile mais dont vous ne pouvez pas vous passer : [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] Ensuite, déclarez d’autres variables que vous devrez utiliser plus tard :
[mw_shl_code=java,true]reload(sys)sys.setdefaultencoding('utf-8&') #将字符编码置为utf-8luckyList=[] #红包列表lowest=10 #能忍受红包领奖记录最低为多少[/mw_shl_code]Une bibliothèque rsa est utilisée ici, qui n’est pas incluse par défaut dans Python. Je dois l’installer :https://pypi.python.org/pypi/rsa/
Après l’avoir téléchargé, lancez setpy.py l’installation, puis nous pourrons commencer nos étapes de développement.
0×02 Connexion Weibo L’action de récupérer les enveloppes rouges doit être effectuée après la connexion, il doit donc y avoir une fonction de connexion, la connexion n’est pas la clé, la clé est la préservation des cookies, ici la coopération de cookielib est requise. [mw_shl_code=java,true]cj = cookielib. CookieJar()opener = urllib2.build_opener(urllib2. HTTPCookieProcessor(cj))urllib2.install_opener(ouvre)[/mw_shl_code] De cette façon, toutes les opérations réseau utilisant l’ouvreur gèrent l’état des cookies, même si je n’en sais pas trop, mais c’est incroyable. Ensuite, il faut encapsuler deux modules, l’un est le module d’acquisition de données, qui sert simplement à obtenir des données, et l’autre à POST-POSTER des données. [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') retourner texte sauf Exception, 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 sauf Exception, e : print u’Request exception, url : '+url[/mw_shl_code] Avec ces deux modules, nous pouvons GET et POST les données, parmi lesquelles la raison pour laquelle getData décode puis encode est que sous Win7 je brouillais toujours la sortie lors du débogage, donc j’ai ajouté un peu de traitement d’encodage, ce n’est pas le but, la fonction de connexion ci-dessous est le cœur de la connexion 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) clé = rsa. PublicKey(rsaPublickey,65537) message = str(servertime) +'\t'+ str(nonce) + '\n'+ str(pwd) sp = binascii.b2a_hex(rsa.encrypt(message,key)) en-tête = {'User-Agent' : 'Mozilla/5.0 (compatible ; MSIE 9.0 ; Windows NT 6.1 ; WOW64 ; Trident/5.0)'} param = { 'entrée' : '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) imprimer u »--------- Connexion réussie ! ------- « print » ----------......---------- « except Exception, e : print u » --------- connexion échouée ! ------- » imprime « ----------......---------- » exit(0)[/mw_shl_code]Les paramètres et algorithmes de chiffrement ici sont copiés d’Internet, je ne comprends pas très bien, il faut probablement demander d’abord un horodatage et une clé publique, puis le chiffrement RSA, puis traiter le traitement et le soumettre à l’interface de connexion Sina, après une connexion réussie depuis Sina, il retournera une adresse Weibo, il faut la demander pour que le statut de connexion puisse prendre pleinement effet, Après une connexion réussie, les requêtes suivantes portent le cookie de l’utilisateur actuel.
0×03 Dessin désigné de l’enveloppe rouge Après m’être connecté avec succès à Weibo, j’ai hâte de trouver une enveloppe rouge pour essayer d’abord, bien sûr, d’abord dans le navigateur. Enfin, j’ai trouvé une page avec un bouton d’enveloppe rouge, F12 a invoqué le débogueur pour voir ce que le paquet de données demandait.
Vous pouvez voir que l’adresse de la requête est http://huodong.weibo.com/aj_hongbao/getlucky, il y a deux paramètres principaux : l’un est ouid, c’est-à-dire l’identifiant de l’enveloppe rouge, visible dans l’URL, l’autre paramètre de partage détermine s’il faut la partager avec Weibo, et il y a un _t dont je ne sais pas à quoi il sert. D’accord, théoriquement, vous pouvez compléter l’extraction des enveloppes rouges en soumettant trois paramètres à cette URL, mais lorsque vous soumettez réellement les paramètres, vous constaterez que le serveur vous retournera magiquement une telle chaîne : [mw_shl_code=java,vrai] {"code » :303403,"msg » :"Désolé, vous n’avez pas la permission d’accéder à cette page »,"data » :[]}[/mw_shl_code] Ne paniquez pas pour l’instant, selon mes nombreuses années d’expérience en développement web, le programmeur de l’autre partie devrait juger le référent, très simple, copier tous les en-têtes de la demande précédente. [mw_shl_code=java,true]def getLucky(id) : #抽奖程序 print u »--- dessiner une enveloppe rouge depuis :"+str(id)+ »--- » print « ----------......---------- » if checkValue(id)==False : #不符合条件, c’est la fonction return plus tard luckyUrl="http://huodong.weibo.com/aj_hongbao/getlucky » param={ 'ouid' :id, 'share' :0, '_t' :0 } en-tête= { '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, comme Gecko) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36', 'X-Requested-With' :'XMLHttpRequest' } res = postData(luckyUrl,param, en-tête)[/mw_shl_code] Dans ce cas, il n’y a pas de problème en théorie, mais en réalité il n’y en a pas. Après la fin de l’action de loterie, il faut juger le statut, et la résolution retournée est une chaîne json, où le code est 100000 est réussi, et si c’est 90114, c’est la limite supérieure de la loterie actuelle, et les autres valeurs sont également échouées, donc : [mw_shl_code=java,true]hbRes=json.loads(res)if hbRes["code"]=='901114' : #今天红包已经抢完 print u »--------- a atteint la limite supérieure--------- » print « ----------......---------- » log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"]) exit(0)elif hbRes["code"]=='100000' :#成功 print u »---------Je vous souhaite prospérité--------- » print « ----------......---------- » log('success',str(id)+'---'+res) exit(0) si hbRes["data"] et 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], où log est aussi une fonction que je personnalise, utilisée pour enregistrer les 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]
|