Python爬虫教程:你还在苦苦拉票吗?刷票案例原理剖析( 二 )
结果
文章插图
具体细节java在java中比较棘手的就是java自身对json和http请求的处理不太方便 , 需要借助第三方jar , 并且一些操作稍显的繁琐 。
首先java要弄清几点:
- 代理方式:java主要有两种代理方式 , 一种是jdk全局代理 , 另一种是net包下的proxy代理 。 对于多线程程序并且ip只能用一次的当然是用net的proxy代理 。
- 解析json通过api获取ip , 格式固定的 , 需要借助fastjson解析json串获取需要的信息 。
- 线程安全问题 。 你可以用线程安全的blockqueue , 当然其实你可以在操作队列的方法加上synchronized关键字也可以 。 你可以定义固定的线程每个线程任务多个 。 也可以用线程池定义多个线程类 , 每个线程完成一个任务 。
- 网络请求虽然urlconnection可以实现 , 但是太繁琐 , 远比jsoup复杂 。 所以这里使用jsoup 。
文章插图
首先你要下载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 = ";count=20 /*** java的多线程和python略有不同 , 但也可以改成相似的 py是5个线程每个线程死循环任务 , 而java用线程池每个线程一个任务 , 只不过new了很多对象** @param args*/ static Queue q1; public static void main(String[] args) {q1=new ArrayDeque();//队列存放结构体 ip和portExecutorService ex= Executors.newFixedThreadPool(10);for(int i=0;i<200;i ){try {Proxy proxy=getproxies(q1);//获得代理ipvote 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);}} elsereturn 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("").timeout(2000);Map date=new HashMap();date.put("id","17");date.put("times","1");date.put("activity","minichallenge1");date.put("Referer",";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
- 缩小|调整电脑屏幕文本文字显示大小,系统设置放大缩小DPI图文教程
- 告诉|阿里大佬告诉你如何一分钟利用Python在家告别会员看电影
- Python源码阅读-基础1
- Python调用时使用*和**
- 如何基于Python实现自动化控制鼠标和键盘操作
- 解决多版本的python冲突问题
- 学习python第二弹
- 更改计算机待机睡眠状态时间方法,电脑设置关闭显示器时间教程
- 随身携带「Windows」Windows To Go制作教程
- Python中文速查表-Pandas 基础