网络爬虫介绍
在大数据时代,信息的采集是一项重要的工作,而互联网中的数据是海量的, 如果单纯靠人力进行信息采集,不仅低效繁琐,搜集的成本也会提高。如何自动 高效地获取互联网中我们感兴趣的信息并为我们所用是一个重要的问题,而爬虫 技术就是为了解决这些问题而生的。 网络爬虫(Web crawler)也叫做网络机器人,可以代替人们自动地在互联网 中进行数据信息的采集与整理。它是一种按照一定的规则,自动地抓取万维网信 息的程序或者脚本,可以自动采集所有其能够访问到的页面内容,以获取或更新 这些网站的内容和检索方式。 从功能上来讲,爬虫一般分为数据采集,处理,储存三个部分。爬虫从一个或 若干初始网页的 URL 开始,获得初始网页上的 URL,在抓取网页的过程中,不断 从当前页面上抽取新的 URL 放入队列,直到满足系统的一定停止条件。
为什么学网络爬虫
我们初步认识了网络爬虫,但是为什么要学习网络爬虫呢?只有清晰地知道我 们的学习目的,才能够更好地学习这一项知识。在此,总结了 4 种常见的学习爬 虫的原因: 1. 可以实现搜索引擎 我们学会了爬虫编写之后,就可以利用爬虫自动地采集互联网中的 信息,采集回来后进行相应的存储或处理,在需要检索某些信息的时候, 只需在采集回来的信息中进行检索,即实现了私人的搜索引擎。
2. 大数据时代,可以让我们获取更多的数据源。 在进行大数据分析或者进行数据挖掘的时候,需要有数据源进行分 析。我们可以从某些提供数据统计的网站获得,也可以从某些文献或内 部资料中获得,但是这些获得数据的方式,有时很难满足我们对数据的 需求,而手动从互联网中去寻找这些数据,则耗费的精力过大。此时就 可以利用爬虫技术,自动地从互联网中获取我们感兴趣的数据内容,并 将这些数据内容爬取回来,作为我们的数据源,再进行更深层次的数据 分析,并获得更多有价值的信息。
3. 可以更好地进行搜索引擎优化(SEO)。 对于很多 SEO 从业者来说,为了更好的完成工作,那么就必须要对 搜索引擎的工作原理非常清楚,同时也需要掌握搜索引擎爬虫的工作原 理。 而学习爬虫,可以更深层次地理解搜索引擎爬虫的工作原理,这样 在进行搜索引擎优化时,才能知己知彼,百战不殆。
4. 有利于就业。 从就业来说,爬虫工程师方向是不错的选择之一,并且随着大数据时代和人工智能的来临,爬虫 技术的应用将越来越广泛,在未来会拥有很好的发展空间。
HttpClient
网络爬虫就是用程序帮助我们访问网络上的资源,我们一直以来都是使 用 HTTP 协议访问互联网的网页,网络爬虫需要编写程序,在这里使用同样 的 HTTP 协议访问网页。 这里我们使用 Java 的 HTTP 协议客户端 HttpClient 这个技术,来实现抓 取网页数据。
不带参数的GET 请求爬取数据
package cn.lala.crawler.httpclient.test;
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;
@SuppressWarnings("all")
public class HttpClientGetTest {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
//不带参数的get请求
HttpGet httpGet = new HttpGet("https://www.baidu.com/");
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String html = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("请求成功,数据的长度是:"+html.length());
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (response != null) {
try { //关闭response
response.close();
//关闭httpClient
httpClient.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
带参数的 GET 请求
package cn.lala.crawler.httpclient.test;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
@SuppressWarnings("all")
public class HttpClientGetParamTest {
public static void main(String[] args) throws URISyntaxException {
CloseableHttpClient httpClient = HttpClients.createDefault();
//带参数的get请求
//HttpGet httpGet = new HttpGet("https://www.baidu.com/s?wd=java");
//创建URIBuilder来构建参数
URIBuilder uriBuilder = new URIBuilder("https://www.baidu.com/s").setParameter("wd", "java");
URI uri = uriBuilder.build();
System.out.println(uri);
HttpGet httpGet = new HttpGet(uri);
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String html = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("请求成功,数据的长度是:" + html.length());
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (response != null) {
try { //关闭response
response.close();
//关闭httpClient
httpClient.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
不带参数的POST 请求爬取数据
package cn.lala.crawler.httpclient.test;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
@SuppressWarnings("all")
public class HttpClientPostTest {
public static void main(String[] args) {
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建HttpPost对象,不带请求参数的post请求
HttpPost httpPost = new HttpPost("https://www.oschina.net/");
//设置请求头,解决网站反爬
httpPost.setHeader("User-Agent","");
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == 200) {
String html = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("请求成功,数据的长度是:"+html.length());
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (response != null) {
try { //关闭response
response.close();
//关闭httpClient
httpClient.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
带参数的 POST 请求
package cn.lala.crawler.httpclient.test;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@SuppressWarnings("all")
public class HttpClientPostParamTest {
public static void main(String[] args) throws UnsupportedEncodingException {
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建HttpPost对象,带参数的post请求
HttpPost httpPost = new HttpPost("https://www.oschina.net/");
//设置请求头,解决网站反爬
httpPost.setHeader("User-Agent","");
//创建List集合封装请求参数
ArrayList pairs = new ArrayList<>();
//使用封装请求参数的List集合,
pairs.add(new BasicNameValuePair("scope","project"));
pairs.add(new BasicNameValuePair("q","httpClient"));
// 创建表单实体对象
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs,"UTF-8");
//把表单实体对象设置到post请求中
httpPost.setEntity(formEntity);
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == 200) {
String html = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("请求成功,数据的长度是:"+html.length());
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (response != null) {
try { //关闭response
response.close();
//关闭httpClient
httpClient.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}