本文主要讲的是如何突破IP限制进行网络投票。
首先前期的准备工作,第一当然得先去获取投票的请求接口以及传参,包括请求头等各种有关的请求信息;
第二就是准备IP代理,百度里有很多免费的IP代理,但是其实能用的没多少,建议还是购买IP代理,购买的IP代理有很多种解析IP的方式,比如网页表格获取解析,json解析等。本文采取的是网页表格获取解析IP。
所需jar包以及工程结构:
IpInfo类:(可根据具体的表格或者获取ip方式调整实体类属性)
public class IpInfo {
private String ipAddress;//ip
private int port;//端口
private String anonymousType;//匿名度
private String type;//类型
private String location;//位置
private String responseSpeed;//响应速度
private String confirmTime;//最后验证时间
public IpInfo() {
super();
}
public IpInfo(String ipAddress, int port, String anonymousType, String type, String location, String responseSpeed,
String confirmTime) {
super();
this.ipAddress = ipAddress;
this.port = port;
this.anonymousType = anonymousType;
this.type = type;
this.location = location;
this.responseSpeed = responseSpeed;
this.confirmTime = confirmTime;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getAnonymousType() {
return anonymousType;
}
public void setAnonymousType(String anonymousType) {
this.anonymousType = anonymousType;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getResponseSpeed() {
return responseSpeed;
}
public void setResponseSpeed(String responseSpeed) {
this.responseSpeed = responseSpeed;
}
public String getConfirmTime() {
return confirmTime;
}
public void setConfirmTime(String confirmTime) {
this.confirmTime = confirmTime;
}
}
IpCollectTask类:(定时获取ip地址)
public class IPCollectTask extends TimerTask{
private BlockingQueue ipInfoQueue; // 连接生产者与消费者的阻塞队列
private List historyIpLists; // 记录已经获取的ip信息
public IPCollectTask(BlockingQueue ipInfoQueue) {
this.ipInfoQueue = ipInfoQueue;
this.historyIpLists = new ArrayList();
}
@Override
public void run() {
System.out.println("开始!!!!");
getKuaiDaiLiFreeIpLists();
}
/**
* 获取IP代理地址
*/
private void getKuaiDaiLiFreeIpLists(){
try {
// 第一次访问,需解析总共多少页
String baseUrl = "http://www.xiongmaodaili.com/freeproxy";//ip地址的页面
Document doc = getDocumentByUrl(baseUrl);//获取网页的对象
Element listNav = doc.getElementById("listnav");//获取分页的div
// 获取listnav下的li列表
Elements liLists = listNav.children().get(0).children();
// 获取含有多少页的子元素
Element pageNumberEle = liLists.get(liLists.size() - 2);
// 解析有多少页
int pageNumber = Integer.parseInt(pageNumberEle.text());
for (int index = 1; index <= pageNumber; index++) {//循环每一页获取ip
baseUrl = tempUrl + index;
doc = getDocumentByUrl(baseUrl);
parseKuaiDaiLiIpLists(doc);
Thread.sleep(10000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据URL解析出dom对象
*/
private Document getDocumentByUrl(String url) {
Document doc = null;
try {
doc = Jsoup.connect(url)
.header("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36")
.header("Host", "www.sgedu.gov.cn")
.timeout(5000)
.get();
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
/**
* 解析IP代理的表格
* @param doc
*/
private void parseKuaiDaiLiIpLists(Document doc) {
Elements eleLists = doc.getElementsByTag("tbody");
Element tbody = eleLists.get(0);//获取表格
Elements trLists = tbody.children();//获取tr
for (Element tr : trLists) {//遍历tr
Elements tdElements = tr.children();//获取td
String ipAddress = tdElements.get(0).text();
int port = Integer.parseInt(tdElements.get(1).text());
String anonymousType = tdElements.get(2).text();
String type = tdElements.get(3).text();
String location = tdElements.get(4).text();
String responseSpeed = tdElements.get(5).text();
//String confirmTime = tdElements.get(6).text();
String confirmTime = "2018/6/25 0:34:05";
IpInfo ipInfo = new IpInfo
(ipAddress, port, anonymousType,type, location, responseSpeed,confirmTime);
putIpInfo(ipInfo);
}
}
/**
* 将已使用过的IP装起来
* @param ipInfo
*/
private void putIpInfo(IpInfo ipInfo) {
if (!historyIpLists.contains(ipInfo)) { // 若历史记录中不包含ip信息,则加入队列中
// 加入到阻塞队列中,用作生产者
try {
ipInfoQueue.put(ipInfo);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 加入历史记录中
historyIpLists.add(ipInfo);
}
}
}
VoteThread类:(多线程发起http请求:(投票/刷票))
public class VoteThread extends Thread{
private BlockingQueue ipInfoQueue;
public VoteThread() {
super();
}
public VoteThread(BlockingQueue ipInfoQueue) {
this.ipInfoQueue = ipInfoQueue;
}
@Override
public void run(){
HttpClient client = new DefaultHttpClient();//创建httpclient对象
//设置请求超时时间
HttpParams params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 15000);
HttpPost post = null;//post请求
HttpResponse response = null;//返回
HttpHost proxy = null;//ip代理
while(true){
try {
IpInfo ipInfo = ipInfoQueue.take();//取IP代理
System.out.println(ipInfo.getIpAddress());
proxy = new HttpHost(ipInfo.getIpAddress(), ipInfo.getPort());//设置ip地址和端口
client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);//设置ip代理
post = new HttpPost("http://www.sgedu.gov.cn/Survey/SurveySave.aspx");//投票接口地址
//请求头信息
post.addHeader("Host", "www.sgedu.gov.cn");
post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36");
//请求参数
ListkvList = new ArrayList<>();
kvList.add(new BasicNameValuePair("Q1","2"));
kvList.add(new BasicNameValuePair("Q1Input",""));
kvList.add(new BasicNameValuePair("SurveyID","12"));
kvList.add(new BasicNameValuePair("Submit","提交问卷"));
StringEntity se = new UrlEncodedFormEntity(kvList,"utf-8");
post.setEntity(se);
response = client.execute(post);//发送请求
String string = EntityUtils.toString(response.getEntity());//返回信息
System.out.println(string);
System.out.println("-----------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Vote类:(程序入口)
public class Vote {
private BlockingQueue ipInfoQueue;
private IPCollectTask ipCollectTask;
private VoteThread voteThread;
public Vote() {
ipInfoQueue = new LinkedBlockingQueue<>();
ipCollectTask = new IPCollectTask(ipInfoQueue);
voteThread = new VoteThread(ipInfoQueue);
}
public void vote() {
Timer timer = new Timer();
long delay = 0;
long period = 1000 * 60 * 60;
// 每一个小时采集一次ip
timer.scheduleAtFixedRate(ipCollectTask, delay, period);
// 开启投票任务
voteThread.start();
}
public static void main(String[] args) {
Vote vote = new Vote();
vote.vote();
}
VoteStart类:(请求测试类,可以先单条测试通过再开启刷票,代码都差不多就不贴了,手动滑稽)
最后PS:此工程是我多年前写的一个工程,可能会有些小问题,请多多见谅,感谢~