【网页爬虫】第一部分 网页请求HttpClient

 爬虫系列博客将从以下几个方面介绍相对编写网页爬虫核心过程。

    【网页爬虫】第一部分        网页请求HttpClient

    爬虫系列】第二部分        网页解析Jsoup

    爬虫系列】第三部分        多线程爬虫框架

   【爬虫系列】第四部分        爬虫日志记录

   爬虫系列】第五部分        url去重


网页请求HttpClient
     HttpClient 是 Apache Common 下的子项目,提供高效的支持 HTTP 协议的客户端编程工具包。HttpClient主要用于模拟浏览器请求url,返回response获取网页数据,然后使用jsoup解析网页,提取我们需要的信息。
一、httpClient发送httpget请求
[java]  view plain  copy
  1. public class HttpClientHello {  
  2.     public static void main(String[] args) throws ClientProtocolException, IOException {  
  3.         // 创建httpclient实例  
  4.         CloseableHttpClient httpClient = HttpClients.createDefault();  
  5.         // 创建httpget实例  
  6.         HttpGet httpGet = new HttpGet("http://www.tuicool.com");  
  7.         // 执行http get 请求  
  8.         CloseableHttpResponse response = null;  
  9.         response = httpClient.execute(httpGet);  
  10.         HttpEntity entity = response.getEntity();// 获取返回实体  
  11.         // EntityUtils.toString(entity,"utf-8");//获取网页内容,指定编码  
  12.         System.out.println("網頁內容" + EntityUtils.toString(entity, "gb2312"));  
  13.         response.close();  
  14.         httpClient.close();  
  15.     }  
  16. }  
二、httpclient模拟浏览器发送请求
     使用httpclient直接发送请求,对于某些安全性较高的网站而言,该httpGet请求会被识别非浏览器代理请求而被拒绝访问。所以一般项目都需要使用httpClient模拟浏览器发送请求,浏览器关键参数。
[java]  view plain  copy
  1. public class HttpClientHello2 {  
  2.     public static void main(String[] args) throws ClientProtocolException, IOException {  
  3.         //创建httpclient实例  
  4.         CloseableHttpClient httpClient=HttpClients.createDefault();  
  5.         //创建httpget实例  
  6.         HttpGet httpGet=new HttpGet("http://www.tuicool.com");  //系統有限制  
  7.         httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36");          
  8.         //执行http get 请求  
  9.         CloseableHttpResponse response=null;          
  10.         response=httpClient.execute(httpGet);  
  11.         HttpEntity entity=response.getEntity();//获取返回实体  
  12.         //EntityUtils.toString(entity,"utf-8");//获取网页内容,指定编码  
  13.         System.out.println("網頁內容"+EntityUtils.toString(entity,"gb2312"));  
  14.         //查看响应类型  
  15.         System.out.println(entity.getContentType().getValue());  
  16.         System.out.println(response.getStatusLine().getStatusCode());    
  17.         //HTTP/1.1 200 OK    200  
  18.         response.close();         
  19.         httpClient.close();       
  20.     }     
  21. }  
HttpGet请求除了访问到指定的url之外,还可设置请求头、请求连接等参数信息。这些参数对于真实浏览器发送的http请求是必不可少的,可通过浏览器-network进行查看具体需要设置哪几种参数以及参数值。

     
     对于返回的 response  httpEntity,可获取实体的内容编码,以及返回状态码来。返回实体信息主要用于特征识别 ,使用content-type过滤调不需要的其他相应类型,例如只要text类型的。
三、采集图片
response返回信息中肯定会有对应图片信息,例如图片验证码、图片二维码等登录凭证。在编写爬虫时,网页中图片的采集方案大致如下:
筛选图片:
确认该请求为图片,根据contentType进行筛选。 获取是图片的请求 ,找到图片,然后处理,另存
保存方式:
1、图片服务器,采集好放到图片服务器中
2、直接存到项目目录下,webapp项目路径下或者缓存中
[java]  view plain  copy
  1. public class HttpClientHello3img {  
  2.     public static void main(String[] args) throws ClientProtocolException, IOException {  
  3.         //创建httpclient实例  
  4.         CloseableHttpClient httpClient=HttpClients.createDefault();  
  5.         //创建httpget实例  
  6.         HttpGet httpGet=new HttpGet("http://cpro.baidustatic.com/cpro/exp/closead/img/bg_rb.png");  //系統有限制  
  7.         httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36");  
  8.           
  9.         //执行http get 请求  
  10.         CloseableHttpResponse response=null;          
  11.         response=httpClient.execute(httpGet);  
  12.         HttpEntity entity=response.getEntity();//获取返回实体  
  13.         //EntityUtils.toString(entity,"utf-8");//获取网页内容,指定编码  
  14.         //System.out.println("網頁內容"+EntityUtils.toString(entity,"gb2312"));  
  15.         //查看响应类型  
  16.         if(entity!=null)  
  17.         {  
  18.             System.out.println(entity.getContentType().getValue());  
  19.             InputStream input=entity.getContent();  
  20.             FileUtils.copyInputStreamToFile(input, new File("C://111.png"));  
  21.         }         
  22.         System.out.println(response.getStatusLine().getStatusCode());    
  23.         //HTTP/1.1 200 OK    200  
  24.         response.close();         
  25.         httpClient.close();       
  26.     }     
  27. }  
这里使用了commons-io, apache IO 框架 copyFileto方法,直接将图片流另存为图片文件到指定路径下。
四、动态更换代理IP
     一般对于访问量大、安全性高的网站都有各自的反爬策略,其中针对定期、规律性访问的IP会进行拉黑屏蔽处理。定向爬取某类网站数据便需要使用大量代理IP进行访问,避免IP被封的情况发生。其中代理IP根据是否易被目标网站发现分为, 透明代理、匿名代理、混淆代理(伪装)、高匿代理(隐蔽性最高,让别人根本无法发现你在使用代理)
     一般如果IP被封,那请求返回状态一般为403,拒绝访问,这时则需要换一个ip再去访问。另外代理 ip管理策略,如果项目没有专门购买批量代理Ip则需要自行在网站上抓代理ip,把抓到的ip都放到先进先出的队列里。n个队列,例如每个40个IP放到1个队列里,队列里<10个了,再去抓。队列里的IP先进先出,避免重复使用。养成代理IP池。

[java]  view plain  copy
  1. public class HttpClientHello4Agent {  
  2.     public static void main(String[] args) throws ClientProtocolException, IOException {  
  3.         //创建httpclient实例  
  4.         CloseableHttpClient httpClient=HttpClients.createDefault();  
  5.         //创建httpget实例  
  6.         HttpGet httpGet=new HttpGet("http://www.tuicool.com");  //系統有限制  
  7.         httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36");  
  8.         HttpHost proxy=new HttpHost("182.204.18.65",8118);  
  9.         RequestConfig config=RequestConfig.custom().setProxy(proxy).build();  
  10.         httpGet.setConfig(config);  
  11.         //执行http get 请求  
  12.         CloseableHttpResponse response=null;          
  13.         response=httpClient.execute(httpGet);  
  14.         HttpEntity entity=response.getEntity();//获取返回实体  
  15.         //EntityUtils.toString(entity,"utf-8");//获取网页内容,指定编码  
  16.         System.out.println("網頁內容"+EntityUtils.toString(entity,"utf-8"));  
  17.         //查看响应类型  
  18.         if(entity!=null)  
  19.         {  
  20.             System.out.println(entity.getContentType().getValue());  
  21.             InputStream input=entity.getContent();  
  22.             FileUtils.copyInputStreamToFile(input, new File("C://111.png"));  
  23.         }         
  24.         System.out.println(response.getStatusLine().getStatusCode());    
  25.         //HTTP/1.1 200 OK    200  
  26.         response.close();         
  27.         httpClient.close();       
  28.     }     
  29. }  
五、 HttpClient连接超时和读取超时
     httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间;
1、连接时间
    是HttpClient发送请求的地方开始到连接上目标url主机地址的时间,理论上是距离越短越快,线路越通畅越快。HttpClient默认连接超时时间是1min,超过1min过一会儿会再次尝试连接。也可人工设定连接超时时间,如10s。

HttpClient读取时间

2、读取时间 

    是HttpClient已经连接到了目标服务器,然后进行内容数据的获取,一般情况 读取数据都是很快速的,但是假如读取的数据量大,或者是目标服务器本身的问题(比如读取数据库速度慢,并发量大等等..)也会影响读取时间。读取时间可也根据业务具体设定。

    HttpClient提供了一个RequestConfig类 专门用于配置参数比如连接时间,读取时间以及代理IP等。

[java]  view plain  copy
  1. public class HttpClientHello5Timeout {  
  2.     public static void main(String[] args) throws ClientProtocolException, IOException {  
  3.         //创建httpclient实例  
  4.         CloseableHttpClient httpClient=HttpClients.createDefault();  
  5.         //创建httpget实例  
  6.         HttpGet httpGet=new HttpGet("http://www.tuicool.com");  //系統有限制  
  7.         httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36");  
  8.           
  9.         RequestConfig config=RequestConfig.custom()  
  10.                     .setConnectTimeout(10000//设置连接超时时间为10s  
  11.                     .setSocketTimeout(10000//设置读取超时时间为10s  
  12.                     .build();  
  13.         httpGet.setConfig(config);  
  14.           
  15.         //执行http get 请求  
  16.         CloseableHttpResponse response=null;          
  17.         response=httpClient.execute(httpGet);  
  18.         HttpEntity entity=response.getEntity();//获取返回实体  
  19.         //EntityUtils.toString(entity,"utf-8");//获取网页内容,指定编码  
  20.         System.out.println("網頁內容"+EntityUtils.toString(entity,"utf-8"));  
  21.         //查看响应类型  
  22.         if(entity!=null)  
  23.         {  
  24.             System.out.println(entity.getContentType().getValue());  
  25.             InputStream input=entity.getContent();  
  26.             FileUtils.copyInputStreamToFile(input, new File("C://111.png"));  
  27.         }         
  28.         System.out.println(response.getStatusLine().getStatusCode());    
  29.         //HTTP/1.1 200 OK    200  
  30.         response.close();         
  31.         httpClient.close();       
  32.     }     
  33. }  









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值