|
0×00 Contexto
Como são os envelopes vermelhos? O filho do irmão, Huer, disse: "O dinheiro é quase comparável. O irmão e a filha Dao Yun disseram: "Não é tão bom quanto minha tia por causa do vento." "Todo mundo entende o contexto, é Ano Novo, e é o dia em que envelopes vermelhos voam pelo céu. Aconteceu que aprendi Python há dois dias, e fiquei mais animado, então estudei e estudei o rastreamento dos envelopes vermelhos do Weibo, por que envelopes vermelhos do Weibo em vez dos envelopes vermelhos do Alipay, porque só entendo a Web, e se eu tiver energia, talvez também estude o algoritmo whack-a-mole no futuro. Como sou iniciante em Python, esse programa também foi o terceiro que escrevi depois de aprender Python, então por favor, não fujem pessoalmente se houver algum buraco no código, o foco está na ideia, bem, se houver algum buraco na ideia, por favor, não mexam pessoalmente, veja bem, o IE tem o rosto de se definir como navegador padrão, eu escrever um artigo ruim também é aceitável...... Eu uso Python 2.7, e dizem que há uma grande diferença entre Python 2 e Python 3.
0×01 Ideias Eu era preguiçoso demais para descrever em palavras, então fiz um esboço, e todo mundo deveria conseguir entender.
Primeiramente, a regra antiga: primeiro introduza uma biblioteca que você não saiba que é útil, mas não pode abrir mão: [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] Depois, declare algumas outras variáveis que você precisará usar depois:
[mw_shl_code=java,true]reload(sys)sys.setdefaultencoding('utf-8&') #将字符编码置为utf-8luckyList=[] #红包列表lowest=10 #能忍受红包领奖记录最低为多少[/mw_shl_code]Uma biblioteca rsa é usada aqui, que não está incluída em Python por padrão. Preciso instalar :https://pypi.python.org/pypi/rsa/
Depois de baixar, execute setpy.py instale e então podemos começar as etapas de desenvolvimento.
0×02 login no Weibo A ação de pegar envelopes vermelhos deve ser realizada após o login, então deve haver uma função de login, o login não é a chave, a chave é a preservação dos cookies, aqui é necessária a cooperação do cookielib. [mw_shl_code=java,true]cj = cookielib. CookieJar()opener = urllib2.build_opener(urllib2. HTTPCookieProcessor(cj))urllib2.install_opener(opener)[/mw_shl_code] Dessa forma, todas as operações de rede usando opener vão lidar com o estado dos cookies, embora eu não saiba muito sobre isso, mas é uma sensação incrível. Em seguida, precisamos encapsular dois módulos, um é o módulo de aquisição de dados, que é usado simplesmente para obter dados, e o outro é usado para POST dados. [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') retorne texto exceto 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() retorne texto exceto Exception, e: print u'Request exception, url: '+url[/mw_shl_code] Com esses dois módulos, podemos GET e POST dados, entre os quais a razão pela qual o getData decode e depois encode é porque no Win7 eu sempre distorcia a saída ao depurar, então adicionei um pouco de processamento de codificação, mas esse não é o objetivo, a função de login abaixo é o núcleo do login do 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] chave de pub = re.findall('"chave de publicação":"(.+?)",' , 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) chave = rsa. PublicKey(rsaPublickey,65537) mensagem = str(servertime) +'\t' + str(nonce) + '\n' + str(pwd) sp = binascii.b2a_hex(rsa.encrypt(message,key)) cabeçalho = {'User-Agent' : 'Mozilla/5.0 (compatível; 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, 'codificação': '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) imprimir u"--------- Login bem-sucedido! ------- "imprimir" ----------......---------- "exceto exceção, e: imprimir u" --------- login falhou! -------" imprimir "----------......----------" exit(0)[/mw_shl_code]Os parâmetros e algoritmos de criptografia aqui são copiados da Internet, não entendo muito bem, provavelmente é pedir primeiro um carimbo de tempo e chave pública, depois criptografia RSA e finalmente processar o processamento e enviar para a interface de login do Sina, após fazer login com sucesso pelo Sina, ele retornará um endereço Weibo, você precisa solicitá-lo para que o status de login tenha efeito completo, Após o login bem-sucedido, as requisições subsequentes carregarão o cookie do usuário atual.
0×03 Desenho designado do envelope vermelho Depois de fazer login com sucesso no Weibo, mal posso esperar para encontrar um envelope vermelho para tentar primeiro, claro, primeiro no navegador. Finalmente, encontrei uma página com um botão vermelho de envelope, F12 invocou o depurador para ver o que o pacote de dados estava solicitando.
Você pode ver que o endereço da solicitação é http://huodong.weibo.com/aj_hongbao/getlucky, há dois parâmetros principais: um é ouid, ou seja, o ID do envelope vermelho, que pode ser visto na URL, o outro parâmetro de compartilhamento determina se compartilhar no Weibo, e há um _t não sei para que serve. Ok, agora teoricamente, você pode completar a extração dos envelopes vermelhos submetendo três parâmetros para essa URL, mas quando você realmente enviar os parâmetros, verá que o servidor magicamente retornará essa string para você: [mw_shl_code=java, verdade] {"code":303403,"msg":"Desculpe, você não tem permissão para acessar esta página","data":[]}[/mw_shl_code] Não entre em pânico neste momento, de acordo com meus muitos anos de experiência em desenvolvimento web, o programador da outra parte deve julgar o referenciador, muito simples, copiar todos os cabeçalhos da solicitação anterior. [mw_shl_code=java,true]def getLucky(id): #抽奖程序 print u"--- desenhar envelope vermelho de:"+str(id)+"---" print "----------......----------" if checkValue(id)==False: #不符合条件, essa é a função return depois luckyUrl="http://huodong.weibo.com/aj_hongbao/getlucky" param={ 'ouid':id, 'share':0, '_t':0 } cabeçalho= { '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, cabeçalho)[/mw_shl_code] Neste caso, não há problema em teoria, mas na verdade não há problema. Após a conclusão da ação da loteria, precisamos julgar o status, e a re retornada é uma string json, onde o código 100000 é bem-sucedido, e se for 90114, é o limite superior da loteria atual, e os outros valores também são falhados, então: [mw_shl_code=java,true]hbRes=json.loads(res)if hbRes["code"]=='901114': #今天红包已经抢完 print u"--------- atingiu o limite máximo---------" print "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"]) exit(0)elif hbRes["code"]=='10000':#成功 print u"---------Desejo prosperidade---------" print "----------......----------" log('sucesso',str(id)+'---'+res) exit(0) se hbRes["data"] e 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], onde log também é uma função que personalizo, usada 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]
|