|
0×00 Antecedentes
¿Cómo son los sobres rojos? El hijo de su hermano, Huer, dijo: "El dinero es casi comparable. El hermano y la hija Dao Yun dijeron: "No es tan bueno como mi tía por el viento." "Todo el mundo entiende el trasfondo, es Año Nuevo y es el día en que sobres rojos vuelan por todo el cielo. Resultó que aprendí Python hace dos días, y estaba más emocionado, así que estudié y estudié el rastreo de sobres rojos de Weibo, por qué sobres rojos de Weibo en lugar de sobres rojos de Alipay, porque solo entiendo la Web, y si tengo energía, quizá también estudie el algoritmo de golpear el topo en el futuro. Como soy principiante en Python, este programa también es el tercero que escribí después de aprender Python, así que por favor no preguntes en persona si hay algún pozo en el código, el enfoque está en la idea, bueno, si hay algún pozo en la idea, por favor no lo provoques en persona, verás, IE tiene la cara de configurarse como navegador predeterminado, escribir un artículo de mala calidad también es aceptable...... Yo uso Python 2.7, y se dice que hay una gran diferencia entre Python 2 y Python 3.
0×01 Ideas Me daba pereza describirlo con palabras, así que hice un boceto, y todo el mundo debería poder entenderlo.
En primer lugar, la antigua regla: primero introduce una biblioteca para la que no sepas que es útil pero que no puedas prescindir: [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] Luego declara otras variables que necesitarás usar más adelante:
[mw_shl_code=java,true]reload(sys)sys.setdefaultencoding('utf-8&') #将字符编码置为utf-8luckyList=[] #红包列表lowest=10 #能忍受红包领奖记录最低为多少[/mw_shl_code]Aquí se utiliza una biblioteca rsa, que por defecto no está incluida en Python. Necesito instalarlo :https://pypi.python.org/pypi/rsa/
Después de descargarlo, ejecuta setpy.py instalación y entonces podemos empezar los pasos de desarrollo.
0×02 Inicio de sesión en Weibo La acción de recoger sobres rojos debe realizarse después de iniciar sesión, por lo que debe haber una función de inicio de sesión; el inicio de sesión no es la clave, la clave es la preservación de cookies, aquí se requiere la cooperación de cookielib. [mw_shl_code=java,true]cj = cookielib. CookieJar()opener = urllib2.build_opener(urllib2. HTTPCookieProcessor(cj))urllib2.install_opener(opener)[/mw_shl_code] De esta manera, todas las operaciones de red que usan opener gestionarán el estado de las cookies, aunque no sé mucho al respecto, pero se siente increíble. A continuación, necesitamos encapsular dos módulos: uno es el módulo de adquisición de datos, que se usa simplemente para obtener datos, y el otro para POST-datos. [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') return text excepto 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 excepto Exception, e: print u'Request exception, url: '+url[/mw_shl_code] Con estos dos módulos, podemos obtener y POSTAR datos, entre los cuales la razón por la que getData decode y luego encode es porque en Win7 siempre distorsionaba la salida al depurar, así que añadí algo de procesamiento de codificación, pero estos no son el punto, la función de inicio de sesión que aparece abajo es el núcleo del inicio de sesión de 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) clave = rsa. PublicKey(rsaPublickey,65537) mensaje = str(servertime) +'\t' + str(nonce) + '\n' + str(pwd) sp = binascii.b2a_hex(rsa.encrypt(message,key)) encabezado = {'User-Agent' : 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'} param = { 'entrada': '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] inicio de sesión=getData(urll) imprimir u"--------- ¡Inicio de sesión exitoso! ------- "imprimir" ----------......---------- "excepto Exception, e: print u" --------- inicio de sesión fallado! -------" imprime "----------......----------" exit(0)[/mw_shl_code]Los parámetros y algoritmos de cifrado aquí se copian de Internet, no lo entiendo muy bien, probablemente sea pedir primero una marca de tiempo y clave pública, luego el cifrado RSA y finalmente procesar el procesamiento y enviarlo a la interfaz de inicio de sesión de Sina, tras iniciar sesión con éxito desde Sina, devolverá una dirección de Weibo, tienes que solicitarla para que el estado de inicio de sesión pueda hacer efecto completo, Tras iniciar sesión correctamente, las solicitudes posteriores llevarán la cookie del usuario actual.
0×03 Dibujo designado del sobre rojo Después de iniciar sesión con éxito en Weibo, estoy deseando encontrar un sobre rojo para probarlo primero, por supuesto, primero en el navegador. Finalmente, encontré una página con un botón rojo de sobre, F12 invocó al depurador para ver qué estaba solicitando el paquete de datos.
Puedes ver que la dirección de la solicitud es http://huodong.weibo.com/aj_hongbao/getlucky, hay dos parámetros principales: uno es ouid, es decir, el id rojo del sobre, que se puede ver en la URL; el otro parámetro de compartir determina si compartirlo con Weibo, y hay un _t no sé para qué sirve. Bien, ahora teóricamente, puedes completar la extracción de sobres rojos enviando tres parámetros a esta URL, pero cuando realmente envíes los parámetros, verás que el servidor mágicamente te devolverá una cadena así: [mw_shl_code=java,true] {"code":303403,"msg":"Lo siento, no tienes permiso para acceder a esta página","data":[]}[/mw_shl_code] No te pongas nervioso en este momento, según mis muchos años de experiencia en desarrollo web, el programador de la otra parte debería juzgar al referente, muy sencillo, copiar todas las cabeceras de la petición anterior. [mw_shl_code=java,true]def getLucky(id): #抽奖程序 imprimir u"--- dibujar un sobre rojo desde:"+str(id)+"---" imprimir "----------......----------" si checkValue(id)==False: #不符合条件, esta es la función return later luckyUrl="http://huodong.weibo.com/aj_hongbao/getlucky" param={ 'ouid':id, 'share':0, '_t':0 } encabezado= { '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, como Gecko) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36', 'X-Requested-With':'XMLHttpRequest' } res = postData(luckyUrl,param, encabezado)[/mw_shl_code] En este caso, en teoría no hay problema, pero en realidad no hay problema. Tras completar la acción de la lotería, necesitamos juzgar el estado, y la resolución devuelta es una cadena json, donde el código 100000 es exitoso, y si es 90114, es el límite superior de la lotería actual, y los demás valores también fallan, así que: [mw_shl_code=java,true]hbRes=json.loads(res)if hbRes["code"]=='901114': #今天红包已经抢完 print u"--------- ha alcanzado el límite superior---------" print "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"]) exit(0)elif hbRes["code"]=='100000':#成功 print u"---------Te deseo prosperidad---------" print "----------......----------" log('éxito',str(id)+'---'+res) exit(0) si hbRes["data"] y hbRes["data"]["título"]: imprimir hbRes["data"]["título"] imprimir "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"])else: print u"---------Error de solicitud---------" print "----------......----------" log('lucky', str(id)+'---'+res)[/mw_shl_code], donde log también es una función que personalizo, que se usa para registrar 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]
|