你还在苦苦拉票吗?前言

剖析投票原理

处理思路

具体实战

主要流程

具体细节python

代码实例python

具体细节java

代码实现java

总结

前言

现在生活中离不开各类的比赛,然而,各个比赛离不开投票,我们会清一色有时候找到我们的朋友在朋友圈发—帮宝贝投一票,帮某某老师,学生投一票。又或许你自己参加比赛,你在为你自己拉票。

剖析投票原理

作为一名程序员,你是否想为自己的生活开一点G呢?熟悉网络请求的我们,应该从问题根源分析问题。对于一个投票的网站。大致分为两类:登录类:

这类网站是确实不太好操作,一般是每个账户每天能够刷若干票。因为账户的资源是有限的,我们很难通过获取大量的账户资源为我们服务。况且,一般的登录稍微大厂或者技术高点其中的js加密会比较复杂,对于普通人js水平不高很难行的通这条路。比如常见需要微信登录,qq登陆的网站投票,就很难开挂。

非登录类:

并不是所有网站都有腾讯的登录授权的,有很多他们自己的官网他们自己就是一个体系。这类网站普通人或许也感觉不到差异:投几票之后也不能投。然后纷纷找朋友帮忙投。剖析这类网站,既然没有登录机制,那么它就是根据ip机制进行鉴定。因为正常你的公网ip相对来说是稳定。所以正常一个用户只能投固定的几票。或许高级一点他会和浏览器信息结合鉴定,但这种还是比较少的。

处理思路

既然原理已经剖析完成,那么剩下的就是设计程序的问题了,对于一个点击投票的事件,它的实质就是一次http(post)请求,然后后台对数据进行更改。那么我们就可以对这个操作流程进行抓包,分析这个请求是那种类型,需要那些参数。然后根据这个请求模拟写出请求。

然而最重要的就是ip代理,你要用代理的ip去访问那个接口,让对方以为是你代理的那个ip再对他访问,所以你需要维护一个代理ip池。对于代理ip池,并不是什么高大上的东西,准确的来说就是一个集合中包含一些可用的ip,能够供我使用。市面上也有很多出售代理ip,也不贵。我用的是蘑菇代理。

具体实战

主要流程

碰巧,最近参加的一个比赛就有拉票环节,如果人为手动拉票的话效率地下,并且你肯定也不会愿意天天去舔人家求情。那就自己分析一波!首先,打开你在的网站(有的手机端,电脑端好抓包可调),谷歌或者其他浏览器F12抓包,点击network,xhr准备(肯定是ajax请求不用想)。

分析这个请求的重要参数.(header)

找到url和几个参数,就可以准备程序了。模拟请求了

具体细节python

因为这是多次请求,所以要考虑性能的问题和效率问题。不能让异常漫天飞,中断,ip白白浪费,或者苦苦等待吧。

对于代理ip,各家卖的虽然有些差异但是大体相同。大致均为卖数量,然后每个ip从开始被用后能够维持几分钟的使用。并且有的ip是不能用的,有的是高延迟的,这些在写程序的时候都要过滤掉。这里面就要考虑下这个程序额设计。多线程:

python虽然多线程有个全局锁大大的影响效率。但是对于io请求型多线程还是能有一定的提速的。因为io有大量的线程等待。多线程的模块大致为定义一个线程类,定义初始方法和run函数。然后在外面定义几个线程,让他们跑任务。

ip处理和资源处理

正常的ip代理是一群ip随机抽取其中作为代理ip,进行爬取任务,然后ip失效从ip池中删除。而url的链接一般放到线程安全的全局容器中一个个抛出。ip放到list或者redis中进行维护,做好try catch异常即可。但是这个刷票只有一个url。并且一个ip只能用有限次数。所以换个思路,url不需要容器维护。而ip用队列维护最好,并且python的队列是线程安全的。所以整个程序的架构也就很清晰了。只需要用个queue解析ip获取的格式进行相应储存。然后被消费,当少于一定个数时,请求api获取ip进行填充。

在预处理方面,以前介绍过另一个蘑菇代理使用和ip池类似的问题,可以预先参考。

代码实例python

import requests

import random

import time

import threading

from queue import Queue

def loadip():

url2 = 'http://piping.mogumiao.com/proxy/api/get_ip_al?appKey=f16367295e284173ae450fc38d9098b3&count=20&expiryDate=0&format=1&newLine=2'

req = requests.get(url2)

date = req.json()

if(date['code'])!='3001':

ipdate2 = date['msg']

global ipdate

ipdate.extend(ipdate2)

for va in ipdate2:

que.put(va)

print(ipdate)

class downspider(threading.Thread):

def __init__(self, threadname, que):

threading.Thread.__init__(self)

self.threadname = threadname

self.que = que

def run(self):

print('start thread' + self.threadname)

while True:

try:

print(self.name,end='')

toupiaospider(que,self.threadname)

except Exception as e:

print(e,'888')

break

def getproxies():

b = ipdate[0]

b=que.get()

d = '%s:%s' % (b['ip'], b['port'])

global proxies

proxies['http'] = d

global msg

msg = b

return proxies

def toupiaospider(que,threadname):

if (que.qsize() < 15): # 拓展ip池

loadip()

proxies2=getproxies()

for i in range(0,5):

try:

#formData['times']=i

req = requests.post(url, headers=header, data=formData, proxies=proxies2, timeout=1.5)

res = req.json()

if res['res']==2001 or req.status_code!=200:

#ipdate.remove(msg)

continue

print(threadname,res,que.qsize())

except Exception as e:

print('errror',e)

# ipdate.remove(msg)

if __name__ == '__main__':

ipdate = []

msg = {}

proxies = {'http': ''}

stadus = 0

que = Queue()

threads=[]#线程

url='http://yunxin.163.com/api/vote/update'

header = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}

formData = {

'Referer':'http://yunxin.163.com/promotion/minichallenge/gallery?from=groupmessage&isappinstalled=0',

'id':'17',

'times':'1',

'activity':'minichallenge1'

}

proxies = {'http': '182.247.92.99:21136',

}

loadip()

time.sleep(5)

threadList = ['thread-1','thread-2','thread-3','thread-4','thread-4']

for j in threadList:

thread = downspider(j, que)

thread.start()

threads.append(thread)

for t in threads:

t.join()

结果

具体细节java

在java中比较棘手的就是java自身对json和http请求的处理不太方便,需要借助第三方jar,并且一些操作稍显的繁琐。

首先java要弄清几点:代理方式:

java主要有两种代理方式,一种是jdk全局代理,另一种是net包下的proxy代理。对于多线程程序并且ip只能用一次的当然是用net的proxy代理。

解析json

通过api获取ip,格式固定的,需要借助fastjson解析json串获取需要的信息。

线程安全问题。你可以用线程安全的blockqueue,当然其实你可以在操作队列的方法加上synchronized关键字也可以。你可以定义固定的线程每个线程任务多个。也可以用线程池定义多个线程类,每个线程完成一个任务。

网络请求虽然urlconnection可以实现,但是太繁琐,远比jsoup复杂。所以这里使用jsoup。

针对上面的问题。写了个demo测试进行预备,对于获取ip的api,大致这种格式

首先你要下载fastjson和jsoup的jar包。或者加入maven依赖。(可在maven官网下jar包)

然后写个demo跑一下

package com.bigsai;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class test2 {

static int va=1;

public static void main(String[] args) {

String ti="{\"code\":\"0\",\"msg\":[{\"port\":\"40034\",\"ip\":\"114.237.64.247\"},{\"port\":\"33257\",\"ip\":\"223.240.210.250\"},{\"port\":\"39618\",\"ip\":\"113.101.255.11\"},{\"port\":\"43151\",\"ip\":\"183.135.106.62\"},{\"port\":\"41795\",\"ip\":\"182.108.44.227\"}]}";

JSONObject jsonObject= JSON.parseObject(ti);

String code=(String) jsonObject.get("code");

JSONArray jsonArray=jsonObject.getJSONArray("msg");

for(Object te:jsonArray)

{

JSONObject team=(JSONObject) te;

String ip=team.getString("ip");

int port=team.getInteger("port");

System.out.println(team " " ip " " port);

}

ExecutorService ex= Executors.newFixedThreadPool(10);

for(int i=0;i<200;i )

{

threadtest threadtest=new threadtest();

ex.execute(threadtest);

}

ex.shutdown();

}

static synchronized void addva()//去掉注释试试

{

va ;

try {

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() " " va);

}

static class threadtest implements Runnable{

@Override

public void run() {

addva();

}

}

}

观察结果。打印,这些边角问题你就明白了。就可以设计java程序了。

代码实现java

package com.bigsai;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;

import org.jsoup.Connection;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.net.Proxy;

import java.util.ArrayDeque;

import java.util.HashMap;

import java.util.Map;

import java.util.Queue;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class wangyi {

// 改成你自己的token已经被我改了

static String ipurl = "http://piping.mogumiao.com/proxy/api/get_ip_al?appKey=f16367295e284173ae3&count=20&expiryDate=0&format=1&newLine=2";

/**

* java的多线程和python略有不同,但也可以改成相似的 py是5个线程每个线程死循环任务,而java用线程池每个线程一个任务,只不过new了很多对象

*

* @param args

*/

static Queue q1;

public static void main(String[] args) {

q1=new ArrayDeque();//队列存放结构体 ip和port

ExecutorService ex= Executors.newFixedThreadPool(10);

for(int i=0;i<200;i )

{

try {

Proxy proxy=getproxies(q1);//获得代理ip

vote vote=new vote(proxy);

ex.execute(vote);

}

catch (Exception e)

{e.printStackTrace();}

}

ex.shutdown();

}

static synchronized Proxy getproxies(Queue q1) throws IOException// 上锁获得代理,因为ip只用一次,也可使用自带的线程安全队列

{

if (q1.size() < 15)// 扩充ip池

{

String jsonva = Jsoup.connect(ipurl).timeout(2500).get().text();

JSONObject jsonObject = JSON.parseObject(jsonva);

String code = (String) jsonObject.get("code");// 状态吗

if (code.equals("0")) {// 正常返回接口

JSONArray jsonArray = jsonObject.getJSONArray("msg");

for (Object jsonobj : jsonArray) {

JSONObject team = (JSONObject) jsonobj;

String ip = team.getString("ip");

int port = team.getInteger("port");

proxynode node = new proxynode(ip, port);

q1.add(node);

}

} else

return null;

}

proxynode proxynode = q1.poll();

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxynode.ip, proxynode.port));

return proxy;

}

static class proxynode// 一个node储存ip和端口

{

String ip;

int port;

proxynode(String ip, int port) {

this.ip = ip;

this.port = port;

}

}

static class vote implements Runnable {

Proxy proxy;

vote(Proxy proxy) {

this.proxy = proxy;

}

public void dovote() throws IOException {

//Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("host", 8888));

try {

Connection connect = Jsoup.connect("http://yunxin.163.com/api/vote/update").timeout(2000);

Map date=new HashMap();

date.put("id","17");

date.put("times","1");

date.put("activity","minichallenge1");

date.put("Referer","http://yunxin.163.com/promotion/minichallenge/gallery?from=groupmessage&isappinstalled=0");

date.put("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");

connect.data(date);

connect.ignoreContentType(true);

connect.proxy(proxy);

Document doc=connect.post();

System.out.println(Thread.currentThread().getName() " " proxy.address() " " doc.text());

}

catch (Exception e)

{

System.out.println(e.toString());

}

}

public void run() {

try {

for(int i=0;i<5;i ) {

dovote();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

结果

总结

在写爬虫还是python方便和简单。因为py对json支持较好(字典),而java强对象类型语法要求较严。但是在多线程方面java肯定是秒杀py的。因为py的多线程是(假)多线程。想提高速度的可以研究多进程。

这类问题本质不难的,做过一次就很简单了。这只是其中一种案例。提供一些思想和解决思路。遇到不同的问题可能需要不同的结构,方式去解决,这就需要融汇贯通。

python爬虫微信刷票_Python爬虫教程:你还在苦苦拉票吗?刷票小程序案例原理剖析!...相关推荐

  1. python 获取用户ip_Python爬虫教程:你还在苦苦拉票吗?刷票小程序案例原理剖析!...

    你还在苦苦拉票吗? 前言 剖析投票原理 处理思路 具体实战 主要流程 具体细节python 代码实例python 具体细节java 代码实现java 总结 点击此处,获取海量Python学习资料! 前 ...

  2. 刷票小程序案例原理剖析(python和java)

    你还在苦苦拉票吗? 前言 现在生活中离不开各类的比赛,然而,各个比赛离不开投票,我们会清一色有时候找到我们的朋友在朋友圈发-帮宝贝投一票,帮某某老师,学生投一票.又或许你自己参加比赛,你在为你自己拉票 ...

  3. python爬虫实验报告_python爬虫实验

    原博文 2013-06-28 13:30 − 那天在新浪微博上看到北北出的题目,由于最近也在做类似的爬虫研究,所以就有了这个实验. 后来在QQ上和北北说了下,要求是啥都抓,就抓乌云的... 然后就开始 ...

  4. python 贴吧自动回复机-Python实现微信自动回复机器人详细教程

    首先,我们需要安装并配置好Python环境,并安装requests和itchat包,我用的是Windows7环境! https://www.python.org/ python官网 下载 然后直接打开 ...

  5. 视频教程-基于python的微信公众号开发教程-微信开发

    基于python的微信公众号开发教程 微信企业号星级会员.10多年软件从业经历,国家级软件项目负责人,主要从事软件研发.软件企业员工技能培训.已经取得计算机技术与软件资格考试(软考)--"信 ...

  6. 微信开放平台绑定各移动应用、网站应用、公众号、小程序、第三方的个数

    微信开放平台绑定各移动应用.网站应用.公众号.小程序.第三方的个数 目前没有在微信的文档中找到过具体的数字,只能真正的登录到后台,并且已经认证了的才能看的到.认证需要300元/年. 很多人都不知道具体 ...

  7. 解决微信开发者工具报错:当前开发者未绑定此AppID,请到小程序后台操作重试

    解决微信开发者工具报错:当前开发者未绑定此AppID,请到小程序后台操作重试 首先要在微信公众平台注册小程序账号,注意与公众号(订阅号)账号区别开来,小程序账号不是公众号账号,登录后小程序账号的界面是 ...

  8. 微信小程序案例TODO备忘录

    微信小程序案例TODO备忘录 微信小程序案例TODO备忘录 本节展示一个制作todo备忘录的案例讲解 代码:https://github.com/Harryjun/WeChatPrj/tree/mas ...

  9. android 微信小程序原理,微信小程序架构原理

    前言 昨日看朋友圈,据说有人花钱买star,不知道真的假的?以前以为只是大家开玩笑.今日早读文章由百度EUX@田光宇投稿分享. 正文从这开始~~ 微信小程序 微信小程序包含下面四种文件: js jso ...

  10. 微信小程序案例一 成绩计算

    微信小程序案例一 :成绩计算 效果图 2.WXML文件 属性 bindinput 的类型为 handlerEvent 除了date/time 类型的输入框,当键盘输入时触发 input 事件,e.de ...

最新文章

  1. GCC 警告选项 -Werror
  2. /sys/class/gpio 文件接口操作IO端口(s3c2440)
  3. why approver preview in Document builder is empty
  4. 想让AI在企业落地?微软最新Azure AI不容错过!
  5. python自带的shell、其性能优于ipython_python3.4 shell
  6. 查找数据库大小和表大小
  7. win10 安装Pytorch GPU版+CUDA+cuDNN(篇幅较长保姆教程) (含CUDA11.1与cuDNN8.0.4安装包)
  8. python param_python发送带param的post请求
  9. Ubuntu 更改源
  10. 在Ubuntu 22.04上安装WRF-Chem模型4.4版本和KPP
  11. MySQL 删除大量数据
  12. ios开发中如何调用苹果自带地图导航
  13. 1-2 李宏毅2021春季机器学习教程-第一节(下)-深度学习基本概念简介
  14. 最新会声会影2023旗舰版更新了哪些功能?
  15. 数据结构|连通图、完全图、无向图、有向图的边数计算问题
  16. 数据链路层 功能概述
  17. 高斯混合模型参数估计的EM算法
  18. 二分查找(序列是顺序的运用递归)
  19. [转]sessionStorage在同一网站多个标签页内共享数据吗?这取决于标签页如何打开
  20. FPGA | Xilinx ISE14.7 LVDS应用

热门文章

  1. 解压文件-提示:“必要的压缩卷不存在”
  2. spring boot layui table.render 加载不了cols
  3. 计算机硬件实验报告怎么写,计算机硬件的认识与组装实验报告怎么写?
  4. psCS6图片文件无法直接拖入的解决方法
  5. javaFX 学习之 超链接(HyperLink) 转载
  6. 在中国移动(中国联通、中国电信)工作是一种怎样的体验?
  7. 1041 考试座位号 (15 分)
  8. 微软的teredo服务器,win10系统通过teredo连接ipv6的具体教程
  9. THREE.JS自定义中心旋转轴
  10. O2OA的流程管理详情