Java爬虫之匿名代理IP的获取

大联盟的各位兄弟姐妹,前辈后生们,大家好,很感谢大家对Java大联盟的关注和支持,继上次的Java爬虫初级入门获得大家的青睐后,时至今日,我又满怀欣喜地为大家奉上这第二篇,文本篇~~~~

爬虫,AI一直是近年来为之关注的焦点,Java以自己独有的严格的语言约束和庞大且成熟的各种框架,成为企业一度的选择,也成为当今码农必知必会的编程语言。

诚然,Java仍然更多地用在WEB开发上,所以学会初级Java爬虫,也是在Java的技能道路上,多看了一处别样的风景。

环境准备:

1. 一个你使用的很顺手的开发工具,(我用IDEA);

2. MAVEN包管理环境;

3. JAR:Jsoup、HTTPClient;

4. 目标站点:某某代理;

5. 一个已经看过上一期爬虫文章,同样期待着这一期的你;

开工:

一、 创建WeChat类,并添加JAR包,如下图:

二、编辑WeChat类,定义一个用于发起HTTP请求的然后返回HTML文本页面的方法:

private String getHTML(String url) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36");
        CloseableHttpResponse response;
        try {
            response = httpClient.execute(httpGet);
            HttpEntity responseEntity = response.getEntity();
            return EntityUtils.toString(responseEntity, "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
}

1、如上图所示,使用HTTPClient创建Http发起者,使用HttpGet,创建GET请求的对象,封装该对象,并使用HTTPClient将其发送到目标站点,获得返回值类型为HTTPResponse,对该响应使用EntityUtils工具统一格式化编码后,将其返回。

PS:被EntityUtils工具处理后,该响应不再为HTTPResponse对象,而是进行了编码后的该Response对象的文本。类型为String。

三、对第二步中的方法进行测试,确保其正确无误,测试及结果如下:

四、承接第二步,我们继续编写用于解析HTML文本的方法,在第二步中我们使用HttPClient发起了GET请求,这里,我们要使用Jsoup解析HTML文本,通过对根节点和子节点的解析,准确获取目标信息,代码如下:

private void doParser(String html) {
        Document document = Jsoup.parse(html);
        Elements elements = document.select("tr.odd");
        for (Element element : elements) {
            String context = element.getAllElements().select("td").text();
            if (context.contains("高匿")) {
                int index_ip = context.indexOf(" ");
                String ip_text = context.substring(0, index_ip);
                String sub_string = context.substring(index_ip, context.length());
                sub_string = sub_string.trim();
                int index_port = sub_string.indexOf(" ");
                String port_text = sub_string.substring(0, index_port);
                System.out.println(ip_text + ":" + port_text);
            }
        }
}

如上所示:定义了名为doParser()的无返回值方法,以String类型的形参HTML为目标,使用Jsoup.parser()方法,将其转化为Document对象,使用select() CSS选择器,查找该HTML中所有的class为“odd”的<tr>标签(在该网页中:class为“odd”的<tr>标签和没有class的<tr>标签是一半一半所以这里只是选择了当前网页的一半的IP,但这拿来使用足矣)。

Select()选择器查找到class为odd的tr标签后,返回Elements对象,使用for each循环遍历得到该Elements中的所有单个element,使用if过滤掉非高匿的IP,从此处开始,正式进入本文的核心环节,也是爬虫的难点所在信息提取!

信息提取详解:

在if条件句中,首先打印出过滤了非高匿IP后的信息,如图:

诚然,没有价值的信息很多,我们需要做文本清洗,剥离出有价值的IP和端口必要信息,将其他繁杂信息舍去~~~

一、IP提取(要点)

分析单行文本可知,若想提取出IP,该行首次出现的“ ”(空格)符号是分割的重点,此处我们使用indexOf()方法,获得第一次出现的“ ”(空格)符号的下标所在,再根据下标,使用substring()方法,将其剥离出来,如图:

这样我们就拿到了IP地址;

一、 端口号的获取(难点)

端口号的获取让我纠结了许久,这也是这篇文章迟迟才出的原因,如果你有更好的办法请不吝赐教。

原本的思路是在API文档中找到一个可以查找当前字符串中某一字符第二次出现的位置并返回下标,然而并没有找到,不是返回最后一次的就是返回第一次的,我百思不得解,一个final的String类竟然不会有这样的方法?为何?这说明该类下的所有已发布方法足矣处理任何String的问题,所以,我开始尝试用不相干的方法,制造合理的利用条件,思路如下:

首先我们来看,在第一步剥离了IP地址后,如果想再次使用IndexOf()方法这样去返回第一个“ ”(空格)字符的下标,然后再根据获得的下标切割去得到关键信息的话,显然IP地址是不应该再存在的,因为在IP地址和port之间已经有一个 “ ”(空格)字符了。所以解决办法第一步,调用substring()方法,使获得的第一个“ ”(空格)字符的下标作为切割的起始下标,字符串的长度为末尾下标,这样我们就得到了一个新的字符串,如下:

但是这仍然不是最适合的剥离环境,因为根据“ ”(空格)字符的下标作为判断依据的话,那么我们还要除去首位的空格(不难发现,每一个端口之前是有一个空格的,仔细看图),调用String.trim()方法,除去字符串首位的空格,得到全新的完美字符串,这时再使用提取IP时的方法就可以得到关于IP和Port的信息,如图:

今天的分享就到这里,谢谢大家。

源码:

链接: https://pan.baidu.com/s/1hEqmdFv7Vola0IxxIGarIw

密码: q2zc

原文发布于微信公众号 - Java大联盟(javaunion)

原文发表时间:2018-05-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

WCF技术剖析之十四:泛型数据契约和集合数据契约(上篇)

在.NET Framework 2.0中,泛型第一次被引入。我们可以定义泛型接口、泛型类型、泛型委托和泛型方法。序列化依赖于真实具体的类型,而泛型则刻意模糊了具...

2398
来自专栏用户2442861的专栏

网易2011笔试题详解

http://blog.csdn.net/silangquan/article/details/18051675

571
来自专栏落影的专栏

iOS开发笔记(一)

前言 iOS开发笔记(一) iOS开发笔记(二) iOS开发笔记(三) iOS开发笔记(四) 《开发笔记》系列记录一些开发中遇到的问题以及思考。 本文主...

3327
来自专栏叁金大数据

自学Python十 爬虫实战三

  我又来送福利啦!!!不同于上篇文章,这次我们的爬虫采用了多线程,一直以来被所谓的分布式  多线程  爬虫 给唬的怕怕的。今天就来一发多线程爬虫吧,还能看妹子...

861
来自专栏Java技术分享

Java基础常见英语词汇

Java基础常见英语词汇(共70个) OO:object-oriented ,面向对象 OOP: object-oriented programming,...

5467
来自专栏前端新视界

CSS 预处理器中的循环

本文由 nzbin 翻译,黄利民 校稿。未经许可,禁止转载! 英文出处:Loops in CSS Preprocessors 发表地址:http://we...

2306
来自专栏企鹅FM

深入浅出Kotlin协程

协程(Coroutines)已经随着Kotlin1.3版本一起发布了1.0正式版,android平台可以使用如下方式引入:

4.7K8
来自专栏Java技术分享

Java基础常见英语词汇

Java基础常见英语词汇(共70个) OO:object-oriented ,面向对象

3037
来自专栏TungHsu

这或许是对小白最友好的python入门了吧——21,导入模块

前边我们提到了定义函数,我们也说过了,定义函数可以让下边引用函数更加方便,“下边”可能还和我们定义函数的代码不在一个文件中,这个时候我们就需要导入函数了。 我们...

3485
来自专栏C/C++基础

CVTE2016春季实习校招技术一面回忆(C++后台开发岗)

2016.3.15,参加了CVTE的技术面,很不幸,我和我的两位小伙伴均跪在了一面。先将当日的面试内容汇总如下,供后来者参考。我们三人各自也都总结了失败的原因,...

611

扫码关注云+社区

领取腾讯云代金券