网络爬虫(一)

网络爬虫(一)

1、爬虫入门案例

public class SpiderDemo {
    public static void main(String[] args) throws IOException {
        // 相当于打开浏览器
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 输入 url 地址
        HttpGet httpGet = new HttpGet("http://news.baidu.com");

        // 得到访问界面的起始时间
        long start = System.currentTimeMillis();

        // 访问地址
        CloseableHttpResponse response = httpClient.execute(httpGet);

        // 得到访问界面的结束时间
        long end = System.currentTimeMillis();

        // 解析返回的值
        if(response.getStatusLine().getStatusCode() == 200){
            // 得到实体
            HttpEntity entity = response.getEntity();

            // 得到页面数据
            String contents = EntityUtils.toString(entity);

            System.out.println((end - start) / 1000);
            System.out.println(contents);
        }

    }
}

浏览器访问某一个网站的流程如下:

  • 打开一个浏览器客户端
  • 输入url
  • 访问
  • 得到响应结果
  • 关闭浏览器

爬虫访问的流程和此我们手动访问浏览器的流程类似

2、请求的配置信息

有时,我们需要对请求增加一些配置,例如对get请求的配置

RequestConfig config = RequestConfig.custom()
                // 创建连接的时间
                .setConnectTimeout(1000)
                // 获取连接的时间
                .setConnectionRequestTimeout(500)
                // 数据传输的时间
                .setSocketTimeout(10000)
                .build();
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(config;

其中配置了3个字段,创建连接的时间、获取连接的时间、数据传输的时间。

3、 带参数的get请求

public static void main(String[] args) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // https://www.baidu.com/s?ie=UTF-8&wd=%E7%99%BE%E5%BA%A6
        URIBuilder uriBuilder = new URIBuilder("http://wwww.baidu.com/s");
    
    	// uriBuilder通过setParameter设置多个参数,可以使用对象链
        uriBuilder.setParameter("ie", "UTF-8")
        		.setParameter("wd", "百度");
		
        HttpGet httpGet = new HttpGet(uriBuilder.build());

    	// try-with-resource
        try(CloseableHttpResponse execute = httpClient.execute(httpGet)) {
            if(execute.getStatusLine().getStatusCode() == 200){
                String content = EntityUtils.toString(execute.getEntity(), "utf-8");
                System.out.println(content);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            httpClient.close();
        }
    }

来看一下这步

img

我们可以把多个get请求的参数设置到UriBuilder中,就是通过setParameter方法

4、带参数的post请求

public class PostParam {
    public static void main(String[] args) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost("https://music.163.com/weapi/login/cellphone");
		
        List<NameValuePair> params = new ArrayList<NameValuePair>();

        params.add(new BasicNameValuePair("params", "43543543"));

        // 得到表单实体
        UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "utf8");
		
        // 设置表实体到post请求中
        httpPost.setEntity(formEntity);

        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            if (response.getStatusLine().getStatusCode() == 200) {
                String comment = EntityUtils.toString(response.getEntity(), "utf8");
                System.out.println(comment);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpClient.close();
        }
    }
}

为什么NameValuePair中放入了一个对象呢,因为NameValuePair是一个接口,可以看到

img

要想在add进去键值对,就需要创建一个NameValuePair的实体类,看一下实现了这个接口的实现类

img

而且该实现类的构造器传入的是一个name和string,所以我们可以把要请求的参数可以直接放在这个集合中

5、HttpClient连接池

为什么使用连接池,学过jdbc的可能知道,频繁的建立连接和销毁连接会带来性能上的影响,浏览器客户端也一样,频繁的开关浏览器进行访问也是会带来性能上的影响的,所以我们使用HttpClient的连接池,每次用的时候直接从池里拿,用完之后归还到池中

public class PoolDemo {
    public static void main(String[] args) throws Exception {
        // 得到连接池管理器
        PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();

        // 设置最大连接数量
        manager.setMaxTotal(100);

        // 每个主机的最大连接数量
        manager.setDefaultMaxPerRoute(10);

        doGet(manager);
    }
    private static void doGet(PoolingHttpClientConnectionManager manager) throws Exception {
        // 建造者模式得到建造者
        HttpClientBuilder clientBuilder = HttpClients.custom();

        CloseableHttpClient httpClient = clientBuilder.build();

        URIBuilder uriBuilder = new URIBuilder("http://wwww.baidu.com/s");

        uriBuilder.setParameter("ie", "UTF-8")
                .setParameter("wd", "百度");

        HttpGet httpGet = new HttpGet(uriBuilder.build());

        CloseableHttpResponse response = httpClient.execute(httpGet);

        if(response.getStatusLine().getStatusCode() == 200){
            String content = EntityUtils.toString(response.getEntity(), "utf8");
            System.out.println(content);
        }
        
        // CloseableHttpClient 使用完后千万不要关闭,千万不要关闭,千万不要关闭,执行完后会自动归还到		     连接池
    }
}

PoolingHttpClientConnectionManager 连接池管理器,其实这就是一个连接池,我们可以从这个池里拿HttpClient客户端,还有就是连接池里的属性了,setMaxTotal这个属性的意思是这个连接池里一共有多少个HttpClient客户端,setDefaultMaxPerRoute这个属性的意思是设置每个主机的最大连接数,何为每个主机的最大连接数呢,例如我们想爬取一些新闻信息,可以同时从百度新闻、今日头条、微博上去获取,但是有一个资源分配的问题,如果我不去限制每台主机的最大连接数,那么可能造成的问题可能就是所有的连接都去爬取百度新闻和今日头条了,就没有去爬取微博的连接了,链接资源都已经被抢占了。

所以就要限制访问每个主机的最大连接数,使其资源分配均匀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值