HTTP协议
HTTP协议简介
HTTP(超文本传输协议)是用于从万维网服务器传输超文本到本地浏览器的传送协议。超文本传输协议(HTTP)是面向事务的(Transaction-oriented),应用层协议规定了在浏览器和服务器之间的请求和响应的格式和规则,它是万维网上能够可靠交换文件(包括文本、声音、图像等各种多媒体文件)的重要基础。
通常,由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是 80端口)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,比如"HTTP/1.1 200 OK",和(响应的)消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。
通过HTTP或者HTTPS协议请求的资源由统一资源标示符(Uniform Resource Identifiers)来标识。
那么如何基于HTTP协议在Java中实现爬虫呢?
1.首先做好准备工作
这是我找到的一个下载壁纸的网页,按F12(或者在菜单-工具)打开开发者工具如下所示:
2.爬取网页中的图片
1).创建一个URL对象获取该网页的统一资源定位符(URL),调用openConnection()方法打开连接,该方法的返回值为一个URLConnection对象,使用HttpURLConnection接收,HttpURLConnection是它的子类。
2).设置请求方式,一般都为GET请求。
3).设置请求头(Header)属性,“User-Agent”,和上图红色框里的值一样,如果不一样会报403错误,意思是禁止恶意访问此网站,不能从此网站中抓取内容。如果是服务器端禁止抓取,那么可以通过设置 User-Agent 来欺骗服务器.。
4).读取该网页的html
5).提取html中的图片 <img src=“https://th.wallhaven.cc/small/y8/y8vlyk.jpg” 。这里我使用的Jsoup和一些if判断语句。调用Jsoup类的静态方法parse()可以解析字符串(html),Document类:网页文档(包含解析到的所有标签) ,Elements类:若干元素Element形成的集合(继承自ArrayList), Element类:某一个html元素。
6).通过输入流和输出流,边读边写(如何通过输入输出流读写图片),将图片写入到指定路径。
代码展示如下:
package my.csdn;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
//爬取网页图片
public class webCrawler {
public static void main(String[] args) {
try {
// 获取 统一资源定位符(url)
URL url = new URL("https://wallhaven.cc/");
// 打开连接
// 应用层:URLConnection
// 传输层:TCP连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方式
connection.setRequestMethod("GET");
// 设置请求Header属性
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));) {
// <img src="https://th.wallhaven.cc/small/y8/y8vlyk.jpg"
String line = null;
while ((line = reader.readLine()) != null) {
line = line.trim();// 去除字符串中的空格
String src = "";
// 使用Jsoup解析字符串
// Document类:网页文档(包含解析到的所有标签)
// Elements类:若干元素Element形成的集合(继承自ArrayList)
// Element类:某一个html元素
Document imageDocument = Jsoup.parse(line);
// 获取imageDocument中所有包含“img”标签的Element对象的集合
Elements elements = imageDocument.getElementsByTag("img");
for (Element element : elements) {
src = element.attr("src");
if (src.startsWith("https://") && src.contains(".jpg")) {
System.out.println(src);//在控制台输出一下看是否正确
// 获取该图片的统一资源定位符()
URL imgUrl = new URL(src);
// 打开连接
HttpURLConnection imgURLConnection = (HttpURLConnection) imgUrl.openConnection();
// imgURLConnection.setRequestProperty("User-Agent", "Mozilla/4.76");
// 获取输入流
BufferedInputStream bis = new BufferedInputStream(imgURLConnection.getInputStream());
// 输出流
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("E:\\image\\壁纸\\" + System.currentTimeMillis() + ".jpg"));
// 边读边写
byte[] buff = new byte[1024];
int len = -1;
while ((len = bis.read(buff)) != -1) {
bos.write(buff, 0, len);
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里我在控制台输出了下看是否图片URL是否正确:
运行结果: