利用HttpClient库下载蚂蜂窝图片

news/2024/11/13 15:43:43/

前言

网络爬虫技术作为互联网数据获取的重要工具,在各行各业都有着广泛的应用。而在本文中,我们将利用Java中的HttpClient库,通过编写一个简单而有效的网络爬虫程序,实现下载蚂蜂窝网站的图片的功能。通过这个例子,我们不仅可以学习如何利用HttpClient库进行网络请求,还可以探索网络爬虫的基本原理和实现方法。

需求场景

假设我们正在开发一个旅游推荐应用,需要从蚂蜂窝网站上获取图片来丰富用户的浏览体验。为了实现这个需求,我们需要编写一个程序来自动下载蚂蜂窝网站上的图片,并保存到本地文件系统中。

目标分析

我们的主要目标是编写一个能够自动下载蚂蜂窝网站图片的程序。为了实现这个目标,我们需要解决以下几个关键问题:

  1. 如何发送HTTP请求并获取网页内容?
  2. 如何从网页内容中提取出图片的URL?
  3. 如何利用HttpClient库下载图片到本地?

爬取方案

爬取遇到的问题

在实现爬取蚂蜂窝图片的过程中,我们可能会遇到以下几个问题:

  1. 反爬机制:蚂蜂窝网站可能会设置反爬机制来阻止爬虫程序的访问,我们需要采取一些措施来规避这些限制,例如设置合适的请求头信息。
  2. 图片URL获取:蚂蜂窝网站上的图片可能分布在不同的页面上,我们需要分析网页结构,找到图片所在的位置,并提取出图片的URL。

完整的爬取过程

下面是完整的爬取蚂蜂窝图片的过程:

  1. 发送HTTP请求:我们使用HttpClient库发送一个GET请求来获取蚂蜂窝网站的HTML页面。
  2. 解析HTML:利用HTML解析器(如Jsoup),我们解析HTML页面,从中提取出所有的图片URL。
  3. 过滤图片URL:对提取出的图片URL进行筛选和过滤,只保留符合我们需求的图片链接。
  4. 下载图片:利用HttpClient库发送HTTP请求,将图片下载到本地文件系统中。

实现代码过程

下面是用Java编写的实现代码示例:

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;public class ImageDownloader {public static void main(String[] args) {String url = "https://www.mafengwo.cn/";List<String> imageUrls = getImageUrls(url);downloadImages(imageUrls);}public static List<String> getImageUrls(String url) {List<String> imageUrls = new ArrayList<>();try {HttpClient httpClient = createHttpClientWithProxy();HttpGet httpGet = new HttpGet(url);HttpResponse response = httpClient.execute(httpGet);HttpEntity entity = response.getEntity();String html = EntityUtils.toString(entity);Document doc = Jsoup.parse(html);Elements imgElements = doc.getElementsByTag("img");for (Element imgElement : imgElements) {String imgUrl = imgElement.absUrl("src");if (!imgUrl.isEmpty()) {imageUrls.add(imgUrl);}}} catch (IOException e) {e.printStackTrace();}return imageUrls;}public static void downloadImages(List<String> imageUrls) {for (String imageUrl : imageUrls) {try {HttpClient httpClient = createHttpClientWithProxy();HttpGet httpGet = new HttpGet(imageUrl);HttpResponse response = httpClient.execute(httpGet);HttpEntity entity = response.getEntity();InputStream inputStream = entity.getContent();String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);OutputStream outputStream = new FileOutputStream("images/" + fileName);byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}inputStream.close();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}public static HttpClient createHttpClientWithProxy() {CredentialsProvider credsProvider = new BasicCredentialsProvider();credsProvider.setCredentials(new AuthScope("www.16yun.cn", 5445),new UsernamePasswordCredentials("16QMSOML", "280651"));HttpHost proxy = new HttpHost("www.16yun.cn", 5445);RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).build();return HttpClients.custom().setDefaultCredentialsProvider(credsProvider).setDefaultRequestConfig(requestConfig).build();}
}

进一步优化

虽然上面的代码可以实现简单的图片下载功能,但在实际应用中,我们可能还需要进行一些优化和改进,以提高下载效率和程序健壮性。下面是一些可能的优化方向:

  • 多线程下载:可以使用多线程技术来提高下载速度,同时避免阻塞主线程。
  • 异常处理:合理处理网络请求过程中可能出现的异常情况,增强程序的健壮性。
  • 连接池管理:使用连接池管理HTTP连接,减少连接创建和销毁的开销,提高性能。
  • 断点续传:支持断点续传功能,当下载中断时可以从上次中断的位置继续下载,节省带宽资源。

http://www.ppmy.cn/news/1438937.html

相关文章

android openGL ES详解

1、渲染线程与主线程的通信 两个线程之间的通信可以用如下方法: 在主线程中的 GLSurfaceView 实例可以调用 queueEvent( &#xff09;方法传递一个 Runnable 给后台渲染线程&#xff0c;渲染线程可以调用 Activity 的 runOnUIThread()来传递事件 (event) 给主线程。 2、顶点…

3.Docker常用镜像命令和容器命令详解

文章目录 1、Docker镜像命令1.1 获取镜像1.2 查看镜像1.2.1、images命令列出镜像1.2.2、tag命令添加镜像标签1.2.3、inspect命令查看详细信息1.2.4、history命令查看镜像历史 1.3 搜索镜像1.4 删除和清理镜像1.4.1、使用标签删除镜像1.4.2、清理镜像 1.5 创建镜像1.5.1、基于已…

js中let和var的区别

在JavaScript中&#xff0c;var、let和const都用于声明变量&#xff0c;但它们之间存在一些重要的区别。特别是let和var之间的区别&#xff0c;我们可以概括为以下几点&#xff1a; 作用域&#xff08;Scope&#xff09;&#xff1a;var有函数作用域或全局作用域&#xff0c;而…

ros的master和apollo的cyber的异同

1、前言 ROS (Robot Operating System) 和 Apollo Cyber RT 是两种不同的机器人操作系统框架&#xff0c;各自设计以满足不同场景下尤其是自动驾驶领域的特定需求。虽然它们在设计理念和核心功能上有相似之处&#xff0c;如提供节点&#xff08;Nodes&#xff09;、消息传递机…

Linux之线程管理

目录 第1关&#xff1a;创建线程 任务描述 相关知识 使用pthread_create函数创建线程 编程要求 答案&#xff1a; 第2关&#xff1a;线程挂起 任务描述 相关知识 使用pthread_join挂起线程 编程要求 答案&#xff1a; 第3关&#xff1a;线程终止 任务描述 相关知识 使用pthread…

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(四)分组多查询注意力

探索和构建 LLaMA 3 架构&#xff1a;深入探讨组件、编码和推理技术&#xff08;四&#xff09;分组多查询注意力 Grouped-query Attention&#xff0c;简称GQA 分组查询注意力&#xff08;Grouped-query Attention&#xff0c;简称GQA&#xff09;是多查询和多头注意力的插值…

让流程图动起来

我们平时画流程&#xff0c;然后贴到文档&#xff0c;就完事了。但是过程演示的时候&#xff0c;如果只是一张静态图&#xff0c;很难吸引到听众的注意力&#xff0c;表达效果并不太好。常用的方法是可以用PPT进行动态演示&#xff0c;做PPT也是需要花一些时间&#xff0c;同时…

循环神经网络实例——序列预测

我们生活的世界充满了形形色色的序列数据&#xff0c;只要是有顺序的数据统统都可以看作是序列数据&#xff0c;比如文字是字符的序列&#xff0c;音乐是音符组成的序列&#xff0c;股价数据也是序列&#xff0c;连DNA序列也属于序列数据。循环神经网络RNN天生就具有处理序列数…