在大数据时代收集信息是非常重要的,但是人工收集效率极低,所以需要自动获取自己想要的数据就不得不用到了网络爬虫。
什么是网络爬虫
网络爬虫也叫作网络机器人,可以代替人们自动去在互联网中进行数据的采集和整理。它是一种按照一定规则,自动抓取万维网中信息的程序或脚本。
网络爬虫一般分为数据采集、处理、存储三个过程。
我们为什么要学爬虫
- 可以实现搜索引擎,可以将网上的数据采集来之后进行处理,然后在采集回来的信息中进行检索,即实现了私人搜索引擎。
- 大数据时代,可以更好的获得更多的数据
- 可以更好地进行搜索引擎优化(SEO)
HttpClient-Get
处理Http的get请求,具体实现的代码如下(无参):
package cn.itcast.crawler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class HttpGetTest {
public static void main(String[] args) {
//创建HttpClient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建HttpGet对象,设置url访问地址
HttpGet httpGet = new HttpGet("http://ztit.zjzhongtian.com:1122/");
//使用HttpClient发起请求,获取response
CloseableHttpResponse response = null;
try {
response=httpClient.execute(httpGet);
//解析响应
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == 200){
String context = EntityUtils.toString(response.getEntity(), "gbk");
System.out.println(context);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭response
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
//关闭httpClient
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
其实过程很明确,首先就是获得HttpClient对象,接着就是用HttpGet发起一个Http请求,之后得到了响应结果,对结果进行处理(当状态码为200时即表示响应成功),这时候就可以对response进行处理了。
而当URI中有参数的时候该怎么办呢?这时候就可以去看HttpGet的源码,发现它的构造方法还有一个:
public HttpGet(final URI uri) {
super();
setURI(uri);
}
所以带参uri可以通过URIBuilder来实现,其他代码不变,就是上文中的HttpGet要做改变:
URIBuilder uriBuilder = new URIBuilder("http://yun.itheima.com/open");
uriBuilder.setParameter("hm","1");
HttpGet httpGet = new HttpGet(uriBuilder.build());
同理,当用到post请求的时候就是使用HttpPost,当要在Post请求中添加参数的时候,需要把参数封装到一个List<>集合中,里面的实体为NameValuePair。这是一个接口,它只有一个实现类BasicNameValuePair。然后创建一个表单entity对象,之后就可以把它添加。
HttpClient连接池
我们上述代码每次请求都要创建和销毁HttpClient,这样会增大内存的开销,HttpClient就可以视作一个浏览器,一个浏览器一直开闭就会影响电脑性能。为了解决这个问题,我们可以类比数据库连接池,实现一个HttpClient连接池来达到复用的效果。
package cn.itcast.crawler;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class HttpClientPoolTest {
public static void main(String[] args) {
//创建连接池管理器
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
//设置最大连接数
poolingHttpClientConnectionManager.setMaxTotal(100);
//设置每个主机的最大连接数
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(10);
//使用连接池管理器发起请求
doGet(poolingHttpClientConnectionManager);
doGet(poolingHttpClientConnectionManager);
}
public static void doGet(PoolingHttpClientConnectionManager cm) {
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
HttpGet httpGet = new HttpGet("http://www.itcast.com");
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode()==200){
HttpEntity entity = response.getEntity();
String context = EntityUtils.toString(entity, "gbk");
System.out.println(context.length());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭response
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
//注意,连接池中的httpClient千万不要去手动关闭
//httpClient.close()
}
}
}