Este artículo es un artículo espejo de traducción automática, por favor haga clic aquí para saltar al artículo original.

Vista: 13448|Respuesta: 5

Cómo conseguir sobres rojos científicamente: Al final del año, puedes hacerte rico y escribir un programa para conseguir sobres rojos

[Copiar enlace]
Publicado en 13/2/2015 22:44:10 | | | |
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]





Anterior:Notas sobre los límites máximos de carga de PHP
Próximo:descarga de extensión dll memcache para PHP5.2, 5.3, 5.4, 5.5
 Propietario| Publicado en 13/2/2015 22:46:37 |
0×04 Rastrear la lista de sobres rojos
Tras la prueba exitosa de una sola acción de recogida de sobres rojos, es el módulo central de gran movimiento de nuestro programa: rastrear la lista de sobres rojos, debería haber muchos métodos y entradas para rastrear la lista de sobres rojos, como varias palabras clave de búsqueda en Weibo y demás, pero yo uso el método más sencillo aquí: rastrear la lista de sobres rojos.
En la página principal (http://huodong.weibo.com/hongbao de la actividad del sobre rojo, a través de varios puntos más, se puede observar todo, aunque la lista está muy conectada, se puede resumir en dos categorías (excepto la lista de sobres rojos más rica): tema y tabla de clasificación.
Siguiendo invocando F12, analiza el formato de ambas páginas, comenzando con una lista de formas temáticas, como: http://huodong.weibo.com/hongbao/special_quyu
Puedes ver que la información del sobre rojo está en un div llamado info_wrap, así que solo necesitamos activar el código fuente de esta página, luego tomar todos los infowraps y simplemente procesarlo para obtener la lista de sobres rojos de esta página, aquí necesitamos usar algunos regulares:
[mw_shl_code=java,true]def getThemeList(url,p):#主题红包 print u"--------- "+str(p)+"page---------" print "----------......----------" html=getData(url+'?p='+str(p)) pWrap= re.compile(r'<div class="info_wrap">(.+?) <span class="rob_txt"></span>',re. DOTALL) #h Obtén info_wrap la clase normal pInfo=re.compile(r'.+<em class="num">(.+)</em>.+<em class="num">(.+)</em>.+<em class="num">(.+).</em>.+href="(.+)" class="btn"',re. DOTALL) #获取红包信息 List=pWrap.findall(html,re. DOTALL) n=len(List) si n==0: return for i in range(n): #traverse all info_wrap div s=pInfo.match(List) #取得红包信息 info=list(s.groups(0))                info[0]=float(info[0].replace('\xcd\xf2','0000')) #现金,ten->0000 try: info[1]=float(info[1].replace('\xcd\xf2','0000')) #礼品价值 excepto Exception, e:                        info[1]=float(info[1].replace('\xd2\xda','00000000')) #礼品价值 info[2]=float(info[2].replace('\xcd\xf2','0000')) #已发送 if info[2]==0: info[2]=1 #防止除数为0 si info[1]==0: info[1]=1 #防止除数为0 info.append(info[0]/(info[2]+info[1])) #红包价值, cash/(número de reclamados + valor del premio) # if info[0]/(info[2]+info[1])>100:                # print url luckyList.append(info) si 'class="page"' en html:#存在下一页 p=p+1 getThemeList(url,p) #递归调用自己爬取下一页[/mw_shl_code]Es tan difícil decir que es tan difícil, y me llevó mucho tiempo escribir estas dos frases. También hay una información en el anexo aquí [4], que es mi algoritmo para juzgar aproximadamente el valor de los sobres rojos, ¿por qué hacer esto? Porque hay muchos sobres rojos pero solo podemos sacar cuatro veces, en el vasto mar de bolsas, debemos encontrar los sobres rojos más valiosos y luego sacarlos, aquí hay tres datos de referencia: valor en efectivo, valor del regalo y número de destinatarios, obviamente si el dinero es pequeño y el número de personas recibiendo muchas personas o el valor del premio es muy alto (algunos incluso son locos en unidades de cientos de millones). Entonces no merece la pena cogerlo, así que me guardé mucho tiempo y finalmente ideé un algoritmo para medir el peso de los sobres rojos: valor del sobre rojo = dinero / (número de destinatarios + valor del premio).
El principio de la página de clasificación es el mismo: encuentra las etiquetas clave y emparejalas regularmente.
[mw_shl_code=java,true]def getTopList(url,daily,p):#排行榜红包 print u"--------- "+str(p)+"page---------" print "----------......----------" html=getData(url+'?daily='+str(daily)+'& p='+str(p)) pWrap=re.compile(r'<div class="list_info">(.+?) <span class="list_btn"></span>',re. DOTALL) #h Get list_info la clase normal pInfo=re.compile(r'.+<em class="num">(.+)</em>.+<em class="num">(.+)</em>.+<em class="num">(.+).</em>.+href="(.+)" class="btn rob_btn"',re. DOTALL) #获取红包信息 List=pWrap.findall(html,re. DOTALL) n=len(List) si n==0: devuelve i en rango(n): #Iterate a través de todos info_wrap div s=pInfo.match(List) #取得红包信息 topinfo=list(s.groups(0))                info=lista(topinfo) info[0]=topinfo[1].replace('\xd4\xaa',') #元->'' info[0]=float(info[0].replace('\xcd\xf2','0000')) #现金,10,>0000 info[1]=topinfo[2]. replace('\xd4\xaa',') #元->'' try: info[1]=float(info[1].replace('\xcd\xf2','0000')) #礼品价值 excepto Exception, e:                        info[1]=float(info[1].replace('\xd2\xda','0000000')) #礼品价值 info[2]=topinfo[0].replace('\xb8\xf6','') #个->'' info[2]=float(info[2].replace('\xcd\xf2','0000')) #已发送                if info[2]==0: info[2]=1 #防止除数为0 si info[1]==0: info[1]=1 #防止除数为0 info.append(info[0]/(info[2]+info[1])) #红包价值, efectivo/(número de destinatarios + valor del regalo)                # if info[0]/(info[2]+info[1])>100: # imprimir la URL luckyList.append(info) si 'class="page"' en html:#存在下一页 p=p+1                getTopList(url,daily,p) #递归调用自己爬取下一页[/mw_shl_code]Bien, ahora podemos rastrear con éxito la lista de las dos páginas especiales, y el siguiente paso es obtener la lista de listas, es decir, la colección de todas estas direcciones de lista, y luego recogerlas una por una:
[mw_shl_code=java,true]def getList(): print u"---------Find target---------" print "----------......----------" themeUrl={ #主题列表 'theme':'http://huodong.weibo.com/hongbao/theme',                 'pinpai':'http://huodong.weibo.com/hongbao/special_pinpai', 'daka':'http://huodong.weibo.com/hongbao/special_daka', 'youxuan':'http://huodong.weibo. com/hongbao/special_youxuan', 'qiye':'http://huodong.weibo.com/hongbao/special_qiye', 'quyu':'http://huodong.weibo.com/hongbao/special_quyu', 'meiti':'http: huodong.weibo.com/hongbao/special_meiti', 'hezuo':'http://huodong.weibo.com/hongbao/special_hezuo' } topUrl={ #排行榜列表 'mostmoney':'http://huodong.weibo. com/hongbao/top_mostmoney', 'mostsend':'http://huodong.weibo.com/hongbao/top_mostsend', 'mostsenddaka':'http://huodong.weibo.com/hongbao/top_mostsenddaka',                'mostsendpartner':'http://huodong.weibo.com/hongbao/top_mostsendpartner', 'cate':'http://huodong.weibo.com/hongbao/cate?type=', 'ropa':'http://huodong.weibo.com/ hongbao/cate?type=clothes', 'beauty':'http://huodong.weibo.com/hongbao/cate?type=beauty', 'fast':'http://huodong.weibo.com/hongbao/cate?type=fast', 'life':'http: huodong.weibo.com/hongbao/cate?type=life', 'digital':'http://huodong.weibo.com/hongbao/cate?type=digital', 'other':'http://huodong.weibo.com/hongbao/cate?type=other'                } para (theme,url) en themeUrl.items(): imprimir "----------"+tema+"----------" imprimir url imprimir "----------......----------"                getThemeList(url,1) para (top,url) en topUrl.items(): print "----------"+top+"----------" print url print "----------......----------"                getTopList(url,0,1) getTopList(url,1,1)[/mw_shl_code]
 Propietario| Publicado en 13/2/2015 22:47:13 |
0×05 Juzgar la disponibilidad de sobres rojos
Esto es relativamente sencillo: primero busca palabras clave en el código fuente para ver si hay un botón rojo para agarrar sobre, y luego ve al ranking de la colección para ver cuál es el registro más alto; si el mayor solo recibe unos pocos dólares, adiós......
La dirección para ver el registro de la colección es http://huodong.weibo.com/aj_hongbao/detailmore?page=1&type=2&_t=0&__rnd=1423744829265&uid=Red ID del sobre

[mw_shl_code=java,true]def checkValue(id): infoUrl='http://huodong.weibo.com/hongbao/'+str(id) html=getData(infoUrl) si 'action-type="lotery"' en html o True: #存在抢红包按钮                logUrl="http://huodong.weibo.com/aj_hongbao/detailmore?page=1&type=2&_t=0&__rnd=1423744829265&uid="+id #查看排行榜数据 param={} cabecera= { 'Cache-Control': 'no-cache', 'Content-Type':'application/x-www-form-urlencoded', 'Pragma':'no-cache', 'Referer':'http://huodong.weibo.com/hongbao/detail? uid='+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(logUrl,param,header) pMoney=re.compile(r'<span class="money">(\d+?. +?) \xd4\xaa</span>', re. DOTALL) #h Recibe a todos list_info habituales luckyLog=pMoney.findall(html,re. DOTALL) si len(logLuckyLog)==0: maxMoney=0 else : maxMoney=float(luckyLog[0]) si maxMoney <más bajo: #记录中最大红包小于设定值 devolver Falso si no: imprime u"--------- mano ralentiza---------" imprime "----------......----------" devuelve falso        volver True[/mw_shl_code]0×06 Trabajo de acabado
Los módulos principales ya están en su lugar, y ahora todos los pasos deben conectarse en serie:
[mw_shl_code=java,true]def start(username,password,low,fromFile): gl=False lowest=low login(nombre de usuario, contraseña) if fromfile=='y': if os.path.exists('luckyList.txt'):                         try: f = archivo('luckyList.txt') newList = [] newList = p.load(f)                                imprimir --------- lista de carga---------' imprimir "----------......----------" excepto Exception, e: imprimir u' no logró analizar la lista local, rastreando la página en línea. 'print "----------......----------" gl=True else: print u' no existe localmente luckyList.txt rastrear páginas online. ' print "----------......----------" gl=True if gl==True: getList() from operator import itemgetter                newList=sorted(luckyList, key=itemgetter(4),reverse=True) f = archivo('luckyList.txt', 'w') p.dump(newList, f) #把抓到的列表存到文件里, así que no necesitas atrapar a f.close() para lucky la próxima vez newList: si no 'http://huodong.weibo.com' en lucky[3]: #不是红包 continuar imprimir lucky[3] id=re.findall(r'(\w*[0-9]+)\w*',lucky[3])                getLucky(id[0])[/mw_shl_code] Como es muy complicado rastrear la lista de sobres rojos repetidamente cada vez que se prueba, añadí un párrafo para volcar la lista completa en el código del archivo, para que puedas leer la lista local y coger el sobre rojo en el futuro.
[mw_shl_code=java,true]if __name__ == "__main__": print u"------------------ Weibo Red Envelope Assistant------------------" print "---------------------v0.0.1---------------------" print u"------------- por @***----------------" Imprimir "-------------------------------------------------" Intenta: uname=raw_input(u"Por favor, introduce tu cuenta de Weibo: ".decode('utf-8').encode('GBK'))                pwd=raw_input(u"Por favor introduzca su contraseña de Weibo: ".decode('utf-8').encode('gbk')) low=int(raw_input(u"Sobre rojo para recibir el máximo de efectivo mayor que n: ".decode('utf-8').encode('gbk'))) fromfile=raw_input(u) Si usar la lista de sobres rojos en la luckyList.txt: (y/n) ".decode('utf-8').encode('gbk')) excepto Exception, e: print u" parameter error" print "----------......----------" print e                exit(0) imprimir u"--------- inicio del programa---------" imprimir "----------......----------" inicio(uname,pwd,low, fromfile) imprimir u" --------- fin del programa--------- "imprimir "----------...... ----------" os.system('pausa')[/mw_shl_code]
0×07 ¡Vamos!

Resumen 0×07
El esqueleto básico del crawler está prácticamente completado, de hecho, todavía hay mucho espacio para que este crawler juegue en muchos detalles, como modificarlo para que soporte inicio de sesión por lotes, como optimizar el algoritmo de valores del sobre rojo; el código en sí también debería tener muchos lugares para optimizar, pero con mi habilidad calculo que puedo conseguirlo.
Al final, todos vieron el resultado del programa, escribí cientos de líneas de código, miles de palabras de artículos, y todo lo que trabajé duro fue conseguir un juego de bolas de dos colores, Nima pit dad, ¡cómo podía ser una bola de dos colores! (Narrador: Cuanto más hablaba el autor, más emocionado se ponía, y de hecho lloraba, y la gente a su alrededor le convencía: Hermano, no es eso, ¿no es solo un sobre rojo de Weibo? Ayer me dolían las manos y no saqué un sobre rojo de WeChat.) )

Publicado en 14/2/2015 7:14:33 |
¿Cuánto dinero conseguiste en Loulou?
Publicado en 2/3/2016 13:48:27 |
Parece tan alto
Publicado en 7/3/2016 12:51:02 |
No sé si es grave
Renuncia:
Todo el software, materiales de programación o artículos publicados por Code Farmer Network son únicamente para fines de aprendizaje e investigación; El contenido anterior no se utilizará con fines comerciales o ilegales; de lo contrario, los usuarios asumirán todas las consecuencias. La información de este sitio proviene de Internet, y las disputas de derechos de autor no tienen nada que ver con este sitio. Debes eliminar completamente el contenido anterior de tu ordenador en un plazo de 24 horas desde la descarga. Si te gusta el programa, por favor apoya el software genuino, compra el registro y obtén mejores servicios genuinos. Si hay alguna infracción, por favor contáctanos por correo electrónico.

Mail To:help@itsvse.com