半途而废的Java爬虫学习经历

最近在面试,发现Java爬虫对于小数据量数据的爬取的应用还是比较广,抽空周末学习一手,留下学习笔记

Java网络爬虫

简单介绍

爬虫我相信大家都应该知道什么,有什么用,主要的用途就是通过程序自动的去获取获取网上的信息数据,写爬出比较出色的就是PY,但是对于小排量的数据而言,java也是可以满足要求的;

HttpClient发起请求

爬虫爬取网页上的数据和我们单独点击链接访问网页数据是同理的,是要使用Http协议访问网页的,这里我们使用Java的Http协议客户端HttpClient来实现抓取网页数据

Hello World

  • 可读性最高的一个列子帮助大家理解一下步骤

带参数的Get请求

带参数的Post请求

post也很简单,和上面几乎一致,改变一下发起请求的方式即可,如下:

当然如果没有携带参数的话,表单对象也是不用创建的,有一个HttpPost对象就可以了

对代码中的对象的解释:

  • NameValuePair : 这是一个接口,点击进去Ctrl + h 发现只有一个实现即:BasicNameValuePair,内有两个属性一个K,一个V

代码优化:连接池

在我们的爬取数据的过程中,HttpClient这个连接对象的创建和销毁是非常频繁的,这里我们使用连接池对其进行优化

public class poolTest {
    public static void main(String[] args) {
        //创建连接池管理器
        PoolingHttpClientConnectionManager pcm = new PoolingHttpClientConnectionManager();
        pcm.setMaxTotal(100);           //设置池内最大连接数
        pcm.setDefaultMaxPerRoute(10);  //设置每个坠机的最大连接数
//从连接池中获取连接对象,而不是单独创建连接对象
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(pcm).build();
​
        HttpGet httpGet = new HttpGet("https://www.cnblogs.com/msi-chen");
        System.out.println(httpGet);
​
        //使用httpClient发起请求,获得响应
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            
            //解析响应,获取到数据
            if (response.getStatusLine().getStatusCode() == 200){
                HttpEntity entity = response.getEntity();
                String content = EntityUtils.toString(entity,"utf8");
                System.out.println(content.length());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (response != null){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //因为我们是连接池中获取到的连接,所以这里不能再给他关闭了
                //httpClient.close();
            }
        }
  
    }
}

获取资源的相关时间配置

Jsoup不是Jsonp

经过上面我们的学习,我们通过HttpClient已经能够抓取到页面了,抓取到页面之后我们可以对其进行解析,可以使用字符串解析工具来对页面进行一个解析,也可以使用正则表达式的方式进行解析,但是这两个方案的开发成本很大,不推荐使用,这里我们学习一个专门解析html页面的技术 Jsonp

Jsoup介绍

jsonp是一款Java的Html解析器,可自己而解析某个url地址、html文本内容,他一共了一套现成的API来去除和操作数据

jsonp的功能:

  • 从一个URL,文字或字符串中解析HTML

  • 使用DOM或者CSS选择器来进行查找,取出数据

  • 可操作HTML元素、属性、文本

Jsoup解析URL

添加Jsoup的依赖即可使用Jsoup

  • 这个是我们待会爬取的页面的一个页面源码

  • 我的的Java代码

    • 可以看大已经获取到我们想要的数据

注意:Jsoup仅仅局限于Html的解析工具使用,而不是替代HttpClient发起请求使用,因为HttpClient支持多线程,连接池,代理等技术,而Jsoup对此的支持不太理想,专业的事交给专业的人,HttpClient去发请求抓数据,Jsoup干解析

Jsoup解析字符串

  • 解析字符串的话,我们随便写一个静态页面,使用根据类把它转换成字符串即可

  • Java代码

Jsoup解析文件

还是上面那个静态页面,我们除了把它转换成String后来解析外,也可以直接对该文件进行解析

使用Dom方式遍历文档

我记得还有一个sax解析吧,那个比较麻烦,现在都快忘记了;

Dom解析,不知道大家有没有听过或者使用过,反正我以前是使用过,不过解析的确实XML,我先简单的介绍一个Dmo方式吧

Dmo解析会把目标文档当成一个对象来处理,先把整个文档加载到内存中,如果文档过于太大,可能内存溢出(一般不会),加载进内存的之后就会构建一颗Dom树,然后才开始提供访问和修改操作

如果你没有学习过,下面我们就通过一个小Demo来学习一下,如果你使用过,我们就权当复习一下:

  • 首先定义一个自定义的html静态页面

Java代码如下:几种常用获取页面数据的api我都演示了一下

元素中获取属性

  • html页面如下

  • Java代码

 

Selector选择器

  • “标签名” :根据标签获取元素

  • #id :根据id获取元素

  • .classValue :根据className获取元素

  • [自定义属性key] :根据属性key获取元素,可以是官方key,亦可为自定义key

  • [属性key=属性value] :根据 k=v 这方式锁定元素,获取数据

下面分别对以上始终选择器的使用做一下演示

  • html页面

  • Java代码

Selector选择器组合使用

  • Java:1

  • html :1

  • Java :2

  • html :2

Hello World级爬虫小案列

在上面的学习中,我们已经知道,HttpClient的作是爬取数据的,而Jsoup是对HttpClient爬取到的数据做一个解析用的,下面我们就赖练习一下这两个工具的使用

搁浅一哈,暂时...日后更新

 

posted @ 2019-09-21 00:34  鞋破露脚尖儿  阅读(562)  评论(0编辑  收藏  举报