精华内容
下载资源
问答
  • java多线程ip代理
    千次阅读
    2019-03-01 19:20:56

    转载自:https://blog.csdn.net/asnet_/article/details/86552290

     

    设置Ip代理很多时候都会有用到,尤其是在写爬虫相关项目的时候。虽然自己目前没有接触这种需求,但由于最近比较闲,就写着当作练习吧
    1
    爬取代理IP
    爬取
    关于爬取代理IP,国内首先想到的网站当然是 西刺代理:https://www.xicidaili.com/。首先写个爬虫获取该网站内的Ip吧。

    先对 国内Http代理 标签页面进行爬取,解析页面使用的Jsoup ,这里大概代码如下

     private List<IPBean> crawl(String api, int index){
            String html = HttpUtils.getResponseContent(api + index);
            System.out.println(html);

            Document document = Jsoup.parse(html);
            Elements eles = document.selectFirst("table").select("tr");

            for (int i = 0; i < eles.size(); i++){
                if (i == 0) continue;
                Element ele = eles.get(i);
                String ip = ele.children().get(1).text();
                int port = Integer.parseInt(ele.children().get(2).text().trim());
                String typeStr = ele.children().get(5).text().trim();

                int type;
                if ("HTTP".equalsIgnoreCase(typeStr))
                    type = IPBean.TYPE_HTTP;
                else
                    type = IPBean.TYPE_HTTPS;

                IPBean ipBean = new IPBean(ip, port, type);
                ipList.add(ipBean);
            }
            return ipList;
        }

    对某些不明白的变量,可以参考我Github
    其中关键的就是css选择器语法,这里需要注意的是不要乱加空格,不然会导致找不到出现空指针。
    css选择器语法具体参考这里 , 这里就不讲解了。

    爬取的信息包括 ip地址、端口号、和代理类型(http或https), 这三个信息我放在IPBean这个类里面。

    过滤
    上面爬取完成后,还要进一步过滤,筛选掉不能使用的。

    筛选大概原理就是先设置上代理,然后请求某个网页,若成功则代表此代理ip有效。
    其中请求成功的标志我们可以直接获取请求的返回码,若为200即成功。

        /**
         * 检测代理ip是否有效
         *
         * @param ipBean
         * @return
         */
        public static boolean isValid(IPBean ipBean) {
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipBean.getIp(), ipBean.getPort()));
            try {
                URLConnection httpCon = new URL("https://www.baidu.com/").openConnection(proxy);
                httpCon.setConnectTimeout(5000);
                httpCon.setReadTimeout(5000);
                int code = ((HttpURLConnection) httpCon).getResponseCode();
                System.out.println(code);
                return code == 200;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }

    注意这里要设置两个超时,连接超时和读取超时。连接超时还好,它默认只是有点长;然而读取超时如果不设置,它好像就会一直阻塞着。
    时间设置为5s就够了,毕竟如果ip有效的话,会很快就请求成功的。这样过滤后,就得到有效的代理ip了

    设置代理
    单次代理
    单次代理表示只在这一次连接中有效,即每次都需要代理。

    http方式的代理非常简单,在URL对象的openConnection方法中加上个Proxy对象即可


     Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipBean.getIp(), ipBean.getPort()));

     connection = (HttpsURLConnection) new URL(url).openConnection(proxy);
    https 稍微复杂点了,中间加上了ssl协议


        /**
         * @param url
         * @param headerMap 请求头部
         * @param ipBean
         * @return
         * @throws Exception
         */
        public static String getResponseContent(String url, Map<String, List<String>> headerMap, IPBean ipBean) throws Exception {
            HttpsURLConnection connection = null;

            // 设置代理
            if (ipBean != null) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipBean.getIp(), ipBean.getPort()));

                connection = (HttpsURLConnection) new URL(url).openConnection(proxy);

                if (ipBean.getType() == IPBean.TYPE_HTTPS) {
                    SSLContext sslContext = SSLContext.getInstance("SSL");
                    sslContext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
                    connection.setSSLSocketFactory(sslContext.getSocketFactory());
                    connection.setHostnameVerifier(new TrustAnyHostnameVerifier());
                }
            }

            if (connection == null)
                connection = (HttpsURLConnection) new URL(url).openConnection();

            // 添加请求头部
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36");
            if (headerMap != null) {
                Iterator<Map.Entry<String, List<String>>> iterator = headerMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, List<String>> entry = iterator.next();
                    List<String> values = entry.getValue();
                    for (String value : values)
                        connection.setRequestProperty(entry.getKey(), value);
                }
            }

            InputStream inputStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            reader.close();
            inputStream.close();
            return stringBuilder.toString();
        }


        private static class TrustAnyTrustManager implements X509TrustManager {

            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[]{};
            }
        }

        private static class TrustAnyHostnameVerifier implements HostnameVerifier {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        }


    这里https方法参考了 这篇博客

    全局代理
    直接上代码,就几行代码

    package util;

    import other.IPBean;

    /**
     * @author Asche
     * @github: https://github.com/asche910
     * @date 2019年1月19日
     */
    public class ProxyUtils {

        /**
         * 设置全局代理
         * @param ipBean
         */
        public static void setGlobalProxy(IPBean ipBean){
            System.setProperty("proxyPort", String.valueOf(ipBean.getPort()));
            System.setProperty("proxyHost", ipBean.getIp());
            System.setProperty("proxySet", "true");
        }

    }


    需要注意一点就是全局只是在该java项目中生效,它不会更改系统中的代理。

    检测
    设置完代理后,也可以用另外一种方法来判断是否代理成功,即直接获取当前ip地址。
    这里我使用的是 https://www.ipip.net/ip.html 这个网站,请求获取html后再解析得到自己的当前ip


     private static final String MY_IP_API = "https://www.ipip.net/ip.html";

        // 获取当前ip地址,判断是否代理成功
        public static String getMyIp() {
            try {
                String html = HttpUtils.getResponseContent(MY_IP_API);

                Document doc = Jsoup.parse(html);
                Element element = doc.selectFirst("div.tableNormal");

                Element ele = element.selectFirst("table").select("td").get(1);

                String ip = element.selectFirst("a").text();

                // System.out.println(ip);
                return ip;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

    优化
    emmm 优化些啥呢???

    速度
    爬取ip时就几个网页,优化估计效果不大。而真正耗时的是检测ip是否有效,因此这里采用多线程,对每个ip的检测请求使用一个线程,最后副线程全部结束后再统计出有多少有效ip。然而问题又来了,怎么判断所有副线程全部结束了呢??? 脑中立刻想到的是join方法,然而仔细想想,才发现这样并不可取。最佳方法应该是设置一个计数器,每个线程结束后计数器加一,然后在主线程循环判断计数器的值是否与线程总数相等即可。由于涉及到并发,需要给某些方法加上锁。这里我代码中实现了,可以参考github

    持久化
    emmm 由于目前只是练练手,并没有这样的需求,比较懒, ( ̄▽ ̄)*
    所以这个需求暂时放放吧,以后有时间再写

    最后github入口:https://github.com/asche910/HttpProxy
    --------------------- 

    转载自:https://blog.csdn.net/asnet_/article/details/86552290

    更多相关内容
  • java多线程代理IP

    2017-11-30 09:35:46
    多线程代理IP池,一直看到有关这方面的技术,最近实现了一个。简单的来说,启动后,会一直定时的获取代理ip,并自动检测代理ip的活跃度。运用多线程的技术,在极短的时间内获取大量的ip进行筛选。架构也比较清楚,...
  • 多线程代理IP

    千次阅读 2017-11-30 10:15:37
    有的时候需要对某些免费接口进行访问,或者数据爬虫时,为了防止某段时间大规模访问,对方封IP的这种情况。在自己进行访问时最好可以尝试换...不买自己百度的话,第一是不够灵活,因为代理ip死亡时间很快,第二是极其麻

                    有的时候需要对某些免费接口进行访问,或者数据爬虫时,为了防止某段时间大规模访问,对方封IP的这种情况。在自己进行访问时最好可以尝试换IP来访问。那么换IP怎么访问,这就牵扯到简单的还是自己动手解决。

    简单的情况下,就是自己买免费的IP,去接接口获取。或者手动配置。缺点是,买免费要钱,在不是公司级业务的情况下,花钱有点冤大头。不买自己百度的话,第一是不够灵活,因为代理ip死亡时间很快,第二是极其麻烦,还要自己找,自己放在变量里?

    所以,最好的解决方式是,要么出钱买一个接口自动获取,要么自己写一个代理ip池,不断地获取新的ip,并进行活跃度检测,删除死亡的ip达到一个转换的效果。

    本文大致讲解一下,多线程代理ip池的思路,有关完整代码在文末提供链接下载。

                  首先,一个代理ip池要从时间逻辑上要考虑以下几个东西

                  1.从那里获取

                  2.怎么获取

                  3.提高获取速度

                  4.保存在哪里

                  5.活跃度怎么保证

                  解决一下上述问题,就能编写出来了。

                  1.既然是免费代理ip池,那就从网上找到提供免费代理ip的网站,从网站上获取

                  2.通过模拟请求,把网站上的代码获取到,通过jsoup解析,获取ip列表

                  3.可以多找一些种子页面,也就是多找几个免费提供代理ip的网站,同时用多线程,同时对多个网站,多个page页面进行解析

                  4.如果很多人要用,放在数据库,如果自己用,放在redis里最好,如果只是学着玩放在static List<String> 里也行

                  5.在启动的时候,开启一个线程对活跃度进行检测,简单的来说,在一定的周期后,此任务启动,会用保存的ip去请求一个网站,如果请求的通,就说明是此Ip可用

                   其实讲到这里基本就不用多说了,这个逻辑还是比较简单的,没有牵扯过多复杂的东西。

                   还是根据对应逻辑点,放几张对应代码的图片,方便理解下吧。

                   1.

                   

                  2.


              

    3.创造线程池,同时对两个网站,前十页的ip进行解析,下面的cheakActive是对活跃度进行检测的,update刷新掉不活跃的ip


    4.选择存储位置,优先选择redis,没有开启redis选择List。抽象父类,下面的redis和list只要继承这个方法实现对应方法,直接掉父类方法就成了


    5.请求超时的删除


    6.结果:




    源码下载地址:java maven的

    http://download.csdn.net/download/zxysshgood/10138666

    展开全文
  • Java,运用了多线程内部执行,不影响其他登录验证操作。在Controller类获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能...
  • java多线程tcp socket server源码很棒的黑客工具 精选的令人敬畏的黑客工具列表。 如果您想为此列表做出贡献,请向我发送拉取请求。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32...
  • java多线程tcp socket server源码很棒的黑客工具 精选的令人敬畏的黑客工具列表。 如果您想为此列表做出贡献,请向我发送拉取请求。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32...
  • 主要介绍了Java实现TCP/IP协议的收发数据(服务端)代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • java多线程tcp socket server源码工具列表 列出下载链接 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32 0.7.1.1 小巧的免费代理服务器。 42zip 42递归 Zip 压缩包炸弹。 acccheck ...
  • 二、爬取原理三、使用步骤方法一爬取网站https://www.kuaidaili.com/验证存取到mysql方法二爬取网站http://www.xicidaili.com/nn/多线程爬取源码 前言 ip池的作用就不多说了 我们在爬虫的时候总是会遇到跑的太频繁...


    前言

    ip池的作用就不多说了
    我们在爬虫的时候总是会遇到跑的太频繁而导致ip被封号,搭建代理ip池是解决的最好方法,本文提供两种简单的利用爬虫搭建代理ip池的方法。


    一、ip池是什么?

    简单来说就是存储一堆ip方便自己调用,用于突破反爬虫机制
    其他作用自行百度


    二、爬取原理

    先爬后验再存
    意思是先去网站爬取有效数据
    通过试验验证ip是否可用
    存储到数据库方便调用(mysql)
    当然你也可以把他写成方法丢到服务器自己来调用
    多线程方法我放到了最后


    三、使用步骤

    方法一

    爬取网站https://www.kuaidaili.com/

    主要代码如下:

    for page in range(91,150):#自己选取要爬页数
        print('==========正在获取第{}页数据============'.format(str(page)))
        base_url='https://www.kuaidaili.com/free/inha/{}/'.format(str(page))
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
        response=requests.get(base_url,headers=headers)
        data=response.text
        html_data = etree.HTML(data)
        
        parse_list=html_data.xpath('//table[@class="table table-bordered table-striped"]/tbody/tr')
        
        for tr in parse_list:
            dict_proxies={}
            http_type=tr.xpath('./td[4]/text()')
            
            ip_num=tr.xpath('./td[1]/text()')
           
            ip_port=tr.xpath('./td[2]/text()')
            
            dict_proxies[http_type[0]]=ip_num[0]+':'+ip_port[0] 
            print(dict_proxies)
            proxies_list.append(dict_proxies)
            time.sleep(0.5)
    

    验证

    主要代码如下:

    def check_ip(proxies_list):
        headers = {
    'Referer':'https://www.liepin.com/',
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
        can_use=[]
        for proxy in proxies_list:
            try:
                
                response=requests.get('https://baidu.com',headers=headers,proxies=proxy,timeout=0.1)
                if response.status_code==200:
                    can_use.append(proxy)
                else:
                    print('不可使用')
            except Exception as e:
                print(e)
            finally:
                print('当前IP',proxy,'通过')
        print(can_use)
        return can_use
    

    通过构造方法,用get请求网址https://baidu.com看是否能用

    存取到mysql

    主要代码如下:

    db = pymysql.connect(
                      host="****",#数据库
                      port=3306,
                      user="****",#用户
                      passwd="****",#密码
                      db="****",#表名
                      charset='utf8'
                      )
    for ip in can_use:
        
        for realip in ip:  
            cursor= db.cursor()    
            sql='INSERT INTO IP地址(IP地址,是否可用) values(%s,%s)'
            cursor.execute(sql,(ip[realip],'可用'))
            db.commit()      
    

    方法二

    验证和存取步骤相同跳过,主要看爬取

    爬取网站http://www.xicidaili.com/nn/

    代码如下:

    url = "http://www.xicidaili.com/nn/"
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
    }
    ip_list = get_ip_list(url,headers=headers)
    proxies = get_random_ip(ip_list)
    canuseIP=check_ip(ip_list)
     
    def get_ip_list(url,headers):
        web_data = requests.get(url,headers=headers)
        soup = BeautifulSoup(web_data.text,'lxml')
        ips = soup.find_all('tr')
        ip_list = []
        #第一个tr是列名
        for i in range(1,len(ips)):
            ip_info = ips[i]
            tds = ip_info.find_all('td')
            ip_list.append(tds[1].text+":"+tds[2].text)
        return ip_list
        
    def get_random_ip(ip_list):
        proxy_list = []
        for ip in ip_list:
            proxy_list.append('http://'+ip)
        proxy_ip = random.choice(proxy_list)
        proxies = {'http':proxy_ip}
        return proxies
    

    多线程爬取

    当然你也可以用多线程爬取,因为我觉得就这样爬就很快了够用了所以我在源码没有放上
    你可以自行加进去
    代码如下:

    with ThreadPoolExecutor(max_workers=5) as t:  # 创建一个最大容纳数量为5的线程池
        task1 = t.submit(pa, (1))   #pa是你爬虫函数
        task2 = t.submit(pa, (2))  # 通过submit提交执行的函数到线程池中
        task3 = t.submit(pa, (3))
        task4 = t.submit(pa, (4))
        task5 = t.submit(pa, (5))
    

    源码

    已上传到github
    可直接使用:链接
    我分了主次,主就是方法一次就是方法二,推荐方法一(快,且大多ip有用)

    展开全文
  • 一直觉得自己之前写的使用定时抓取构建IP代理池实在过于简陋,并且有一部分的代码写的并不合理,刚好最近又在学习多线程,就将之前的代码进行了重构,也方便对抓取代理ip有需求的人。之前自己写的那篇文章就不删除了...

    一直觉得自己之前写的使用定时抓取构建IP代理池实在过于简陋,并且有一部分的代码写的并不合理,刚好最近又在学习多线程,就将之前的代码进行了重构,也方便对抓取代理ip有需求的人。之前自己写的那篇文章就不删除了,里面用到了MySQL以及循环调用ip的方法(一些东西也是值得了解的。取其精华,弃其糟粕吧),大家有兴趣的可以看一下(最主要的还是不舍得访问量,哈哈)。

    注:由于xici代理网的ip代理并不是很稳定,所以自己实现的ip代理池并不可用(4000个IP最后通过一系列逻辑处理和过滤之后大概只剩30多个,并且这30个ip也极不稳定),但感觉实现ip代理池的原理就是这样,在往后估计也就是性能上的优化。虽然ip代理池并不可用,但是如果你想要学习多线程以及抓取ip做爬虫的话,这篇文章我觉得是可以给你一些思路上的启发。


    怎么设计一个IP代理池

    其实设计一个IP代理池是非常容易的一件事情,我们来看一下其中的步骤:

    1.首先肯定是从提供代理ip的网站上对ip进行抓取

    2.对抓取下来的ip进行初步的过滤,比如我一开始就将IP类型不是HTTPS并且IP链接速度大于2秒的给过滤掉了

    3.对于符合我们要求的IP,我们要对其进行质量检测,判断其是否可用,这一步就是检测IP的质量,也就是这一步刷掉了大量的IP

    4.将符合要求的ip写进Redis数据库中,我是以List形式存储在Redis中

    5.设定一个进行抓取的周期,来更新你的IP代理池(在将新的IP抓取下来并进行处理之后,我们将原数据库清空,并将新的IP写入其中)

    第五个我是直接每次先清空数据库,然后在进行新IP的抓取以及过滤然后才写入数据库中,这样明显是不合理的,因为它会造成你的IP代理池有很长一段时间是空缺的,这也是我在写这篇博客的时候才想到的一个不合理的地方(太懒,代码也就不改了,大家知道问题就行)。


    整体架构

    这里写图片描述


    实现细节

    HttpResponse的阻塞

    在我们用代理IP进行网页抓取的时候,经常会发生长时间的阻塞然后程序报错(具体原因不祥,如果你真的有兴趣弄明白,建议看源码),这个时候我们只要设定好链接时间并进行恰当的try,catch就可以解决这个问题。

    如下面代码:

    /**
     * setConnectTimeout:设置连接超时时间,单位毫秒.
     * setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒.
     * 这个属性是新加的属性,因为目前版本是可以共享连接池的.
     * setSocketTimeout:请求获取数据的超时时间,单位毫秒.如果访问一个接口,多少时间内无法返回数据,
     * 就直接放弃此次调用。
     */
    
    HttpHost proxy = new HttpHost(ip, Integer.parseInt(port));
    RequestConfig config = RequestConfig.custom().setProxy(proxy).setConnectTimeout(3000).setSocketTimeout(3000).build();
    HttpGet httpGet = new HttpGet(url);
    httpGet.setConfig(config);
    try {
        //客户端执行httpGet方法,返回响应
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
    
        //得到服务响应状态码
        if (httpResponse.getStatusLine().getStatusCode() == 200) {
            entity = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
        }
    
        httpResponse.close();
        httpClient.close();
        } catch (ClientProtocolException e) {
            entity = null;
        } catch (IOException e) {
            entity = null;
        }
    
        return entity;
    }

    线程类的实现

    多线程需要注意的就是一点:线程安全,还有就是保证线程同步而不发生脏读,这些东西需要结合整体代码逻辑去把握,我就在这里不细说了。考虑大家有可能产生疑惑,所以我在代码中进行了详细的注释,大家有兴趣的可以在我github上查看源码,有不懂的或有疑惑的同学欢迎在评论区提问与讨论。

    我贴一下提供多线程抓取代理ip的服务类:

    public class IPPool {
        //成员变量(非线程安全)
        private List<IPMessage> ipMessages;
    
        public IPPool(List<IPMessage> ipMessages) {
            this.ipMessages = ipMessages;
        }
    
        public void getIP(List<String> urls) {
            String ipAddress;
            String ipPort;
    
            for (int i = 0; i < urls.size(); i++) {
                //随机挑选代理IP(仔细想了想,本步骤由于其他线程有可能在位置确定之后对ipMessages数量进行增加,虽说不会改变已经选择的ip代理的位置,但合情合理还是在对共享变量进行读写的时候要保证其原子性,否则极易发生脏读)
    
                //每个线程先将自己抓取下来的ip保存下来并进行过滤与检测
                List<IPMessage> ipMessages1 = new ArrayList<>();
                String url = urls.get(i);
    
                synchronized (ipMessages) {
                    int rand = (int) (Math.random()*ipMessages.size());
                    out.println("当前线程 " + Thread.currentThread().getName() + " rand值: " + rand + " ipMessages 大小: " + ipMessages.size());
                    ipAddress = ipMessages.get(rand).getIPAddress();
                    ipPort = ipMessages.get(rand).getIPPort();
                }
    
                //这里要注意Java中非基本类型的参数传递方式,实际上都是同一个对象
                boolean status = URLFecter.urlParse(url, ipAddress, ipPort, ipMessages1);
                //如果ip代理池里面的ip不能用,则切换下一个IP对本页进行重新抓取
                if (status == false) {
                    i--;
                    continue;
                } else {
                    out.println("线程:" + Thread.currentThread().getName() + "已成功抓取 " +
                    url + " ipMessage1:" + ipMessages1.size());
                }
    
                //对ip重新进行过滤,只要速度在两秒以内的并且类型为HTTPS的
                ipMessages1 = IPFilter.Filter(ipMessages1);
    
                //对ip进行质量检测,将质量不合格的ip在List里进行删除
                IPUtils.IPIsable(ipMessages1);
    
                //将质量合格的ip合并到共享变量ipMessages中,进行合并的时候保证原子性
                synchronized (ipMessages) {
                    out.println("线程" + Thread.currentThread().getName() + "已进入合并区 " + "待合并大小 ipMessages1:" + ipMessages1.size());
                    ipMessages.addAll(ipMessages1);
                }
            }
        }
    }

    将IPMessages(保存IP信息的对象)写入Redis中

    由于Redis只支持字符串与字节流数据,所以我们要想将一个对象存储到Redis的List中,则必须将对象序列化(转换成字节流),反之,如果我们想要将Redis中的数据拿出来,就要反序列化。关于序列化与反序列化的知识不懂的大家百度,我就不细说了。来看一下这部分的代码:

    序列化以及反序列化(Java中好像有现成的方法,我没有具体了解):

    /**
     * Created by hg_yi on 17-8-9.
     *
     * java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法
     * 可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
     *
     * java.io.ObjectInputStream代表对象输入流,它的readObject()方法一个源输入流中读
     * 取字节序列,再把它们反序列化为一个对象,并将其返回。
     *
     * 对象序列化包括如下步骤:
     * 1)创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流(我这里是字节流);
     * 2)通过对象输出流的writeObject()方法写对象。
     *
     * 对象反序列化的步骤如下:
     * 1)创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流(我这里是字节流);
     * 2)通过对象输入流的readObject()方法读取对象。
     */
    
    public class SerializeUtil {
        public static byte[] serialize(Object object) {
            ObjectOutputStream oos;
            ByteArrayOutputStream baos;
    
            try {
                // 序列化
                baos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(baos);
                oos.writeObject(object);
    
                byte[] bytes = baos.toByteArray();
    
                return bytes;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //反序列化
        public static Object unserialize(byte[] bytes) {
            ByteArrayInputStream bais;
            ObjectInputStream ois;
    
            try {
                // 反序列化
                bais = new ByteArrayInputStream(bytes);
                ois = new ObjectInputStream(bais);
    
                return ois.readObject();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return null;
        }
    }

    最后,定时任务的实现我没有再用第一篇博客里面讲的quartz,代码太多并且不好理解。当时太年轻,还不知道Timer这个Java自带的产生定时任务的类,它的实现相当于是开了一个单独的线程去帮助执行我们所设定的任务,它的用法我就不细说了,源码里有,非常方便,并且代码量也很少。

    好了,废话说了这么多,贴上大家想要的东西:

    戳我获得源码哦~

    展开全文
  • java多线程tcp socket server源码黑客工具 Enlaces de interés con multitud de herramientas hacking。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32 0.7.1.1 小巧的免费代理...
  • java多线程tcp socket server源码很棒的黑客工具 精选的令人敬畏的黑客工具列表。 如果您想为此列表做出贡献,请向我发送拉取请求。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32...
  • java多线程tcp socket server源码很棒的黑客工具 精选的令人敬畏的黑客工具列表。 如果您想为此列表做出贡献,请向我发送拉取请求。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32...
  • import java.io.IOException; import java.net.URL; import java.util.List; public class FetchProxyIpUtil { public static List getProxyIp() throws IOException { List proxyIpList = Lists.newArrayList(); /...
  • java 多线程给Callable传递参数

    万次阅读 热门讨论 2018-06-21 10:53:15
    通过实现Callable接口,实现多线程程序时发现, call方法为@Override的无法直接在方法上传递参数,在网上找到了解决办法,通过构造方法传递参数放上代码 private int taskNum; private String ip; private ...
  • java多线程tcp socket server源码很棒的黑客工具 精选的令人敬畏的黑客工具列表。 如果您想为此列表做出贡献,请向我发送拉取请求。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32...
  • java抓取技术源码 多线程爬虫--抓取淘宝商品详情页URL 本项目是一个Java编写的多线程爬虫系统。此系统与我之前开发的结合使用,共抓取了淘宝近3000个页面,...IP代理池 mainmethod Main方法入口 mythread 项目相关线
  • 爬虫(第一篇) IP代理

    千次阅读 2021-01-27 16:31:01
    搞虫子的都知道,IP代理是必要的方法...第一:线程池,线程检测 package com.*.util.thread; import org.apache.log4j.Logger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Ex
  • 一、概念梳理 1、Socket是什么? Socket是应用层与TCP/IP协议族通信...目前java动态代理的实现分为两种 1.基于JDK的动态代理 2.基于CGILB的动态代理 在业务中使用动态代理,一般是为了给需要实现的方法添加预处理
  • Java:爬取代理ip,并使用代理IP刷uv

    千次阅读 2020-06-26 11:23:50
    网站对访问量的判断并不严格,只要页面被点击即视为有效访问,但是应该现在反爬虫越来越严格,为防止部分网站会对IP进行拉黑,所以这里写一个小程序爬取代理IP,并使用代理IP刷访问量。原本想把代理IP包装成一个...
  • Java网络爬虫(七)--实现定时爬取与IP代理

    万次阅读 多人点赞 2017-04-27 20:22:21
    注:对代码及思路进行了改进—Java网络爬虫(十一)–重构定时爬取以及IP代理池(多线程+Redis+代码优化) 定点爬取 当我们需要对金融行业的股票信息进行爬取的时候,由于股票的价格是一直在变化的,我们不可能...
  • 本篇文章涉及到的集中比较流行的爬虫技术,包括IP代理多线程,scrapy,cookie等,
  • 如何实现java多线程?

    2022-04-23 16:37:33
    关于java多线程的文章早已是非常多了,本文是对我个人过往学习java,理解及应用java多线程的一个总结。此文内容涉及java多线程的基本原理,以及如何实现java多线程?希望对大家有所帮助。 如何实现java多线程? Java...
  • java中如何做展示 IP 属地功能
  • 在本实验中,您将了解Web代理服务器的工作原理及其基本功能之一 —— 缓存。 您的任务是开发一个能够缓存网页的小型Web代理服务器。这是一个很简单的代理服务器,它只能理解简单的GET请求,但能够处理各种对象 —— ...
  • Java中使用多线程、curl及代理IP模拟post提交和get访问 菜鸟,多线程好玩就写着玩,大神可以路过指教,小弟在这受教,谢谢! /** * @组件名:javaDemo * @包名:javaDemo * @文件名:Jenny.java * @创建时间...
  • 大数据量处理、多线程和高并发的问题一直是Java技术面试中比较喜欢问的问题之一,遂在此做个总结 一、数据量太大获取缓慢怎么办? 貌似这个问题在所有开发的应用系统中都会碰到这个问题,随着时间的推移,由于需求...
  • 最近在写博客浏览量的时候,设计了这么一个逻辑:同一个IP浏览一遍文章,5分钟内不刷新次数。就需要在服务器端得到用户的真实IP,我代码是这样写的(从网上找的方法): public static String getRealIp...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 49,413
精华内容 19,765
关键字:

java多线程ip代理