大家好,欢迎来到IT知识分享网。
先做一个调研,现在传统的Java后端非常卷,不太好找工作,大家有没有兴趣用Java搞爬虫(本人就是后端转爬虫),我接下来可以出关于爬虫类的文章,包括ip、js逆向、cookie反爬、请求响应参数加解密、浏览器指纹分析及常见的反爬手段。评论区告诉我!!!
可能大部分用户觉得,数据爬取方面 python 很厉害,其实 java 也很厉害,比如我们今天要介绍的这款工具库:Jsoup。
官方解释如下:
jsoup 是一个用于处理 HTML 的 Java 库。它提供了一些非常方便的 API,用于提取和操作 HTML 页面数据,比如 DOM,CSS 等元素。
由于 jsoup 的 API 方法使用上与 jQuery 极其接近,因此如果你了解过 jQuery,那么可以轻而易举地上手这款框架。
那么如何使用它呢,下面我们一起来看看!
maven:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.2</version>
</dependency>
一、爬取网站图片
在爬取网站图片之前,我们需要分析该网站的结构。我们可以使用浏览器的开发者工具来查看网站的源代码。打开该网站后,我们可以在浏览器的菜单栏中点击“工具”-“开发者工具”,然后切换到“网络”标签,刷新页面,就可以看到该网站的请求。
通过查看请求,我们可以看到该网站的图片是通过以下接口获取的:http://www.cgtpw.com/ctmn/ajax.php?act=ctmn&cat_id=0&page=1。其中,page表示页码。我们可以通过修改page的值来获取不同页的图片。
了解了网站的结构之后,我们就可以开始编写Java程序来爬取该网站的图片了。
二、异步下载图片
在爬取图片时,我们需要注意两个问题:下载图片的数量和下载图片的速度。如果一次性下载大量图片,会占用太多的内存和网络带宽,导致程序运行缓慢。另外,如果下载速度过慢,也会影响程序的运行效率。因此,我们需要采用异步下载的技术来解决这个问题。
Java提供了多种异步下载图片的方式,比如使用线程池、使用Java 8中的CompletableFuture等。本文将介绍使用Java 8中的CompletableFuture来异步下载图片。
首先,我们需要创建一个方法来下载图片。该方法接受一个图片的URL作为参数,返回一个CompletableFuture对象,该对象用于异步下载图片。代码如下:
private static CompletableFuture<Void> downloadImage(String imageUrl) {
return CompletableFuture.runAsync(() -> {
try {
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
File file = new File("images/" + fileName);
InputStream inputStream = conn.getInputStream();
FileOutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
inputStream.close();
outputStream.close();
System.out.println("Downloaded: " + fileName);
} else {
System.out.println("Failed to download: " + imageUrl);
}
} catch (Exception e) {
System.out.println("Failed to download: " + imageUrl + ", " + e.getMessage());
}
});
}
该方法通过异步方式下载图片,并保存到images目录下。如果下载成功,则打印“Downloaded: 文件名”,否则打印“Failed to download: 图片URL”。
接下来,我们需要编写一个方法来批量下载图片。该方法接受一个图片URL列表作为参数,使用CompletableFuture.allOf()方法将所有异步下载任务合并为一个CompletableFuture对象,并使用join()方法等待所有任务完成。代码如下:
private static void downloadImages(List<String> imageUrls) {
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (String imageUrl : imageUrls) {
futures.add(downloadImage(imageUrl));
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).join();
}
该方法将所有异步下载任务合并为一个CompletableFuture对象,并使用join()方法等待所有任务完成。
三、翻页爬取
由于该网站的图片是分页显示的,因此我们需要编写一个方法来翻页爬取。该方法接受一个页码作为参数,获取该页的图片URL列表,并调用异步下载方法下载图片。代码如下:
private static void crawlPage(int page) {
try {
String url = "http://www.cgtpw.com/ctmn/ajax.php?act=ctmn&cat_id=0&page=" + page;
Document doc = Jsoup.connect(url).get();
Elements elements = doc.select("div.list-box img");
List<String> imageUrls = new ArrayList<>();
for (Element element : elements) {
String imageUrl = element.attr("data-src");
imageUrls.add(imageUrl);
}
downloadImages(imageUrls);
} catch (Exception e) {
System.out.println("Failed to crawl page: " + page + ", " + e.getMessage());
}
}
该方法通过Jsoup库获取网页内容,并解析出图片URL列表。然后调用异步下载方法下载图片。如果下载失败,则打印“Failed to crawl page: 页码,错误信息”。
最后,我们可以编写一个main方法来执行翻页爬取的任务。该方法可以指定起始页码和结束页码,循环爬取每一页的图片。代码如下:
public static void main(String[] args) {
int startPage = 1;
int endPage = 10;
for (int i = startPage; i <= endPage; i++) {
crawlPage(i);
}
}
该方法从startPage开始,循环爬取每一页的图片,直到endPage结束。
四、总结
本文介绍了如何用Java实现爬取http://www.cgtpw.com/ctmn这个网站图片的过程,并采用异步下载和翻页爬取的技术,以提高爬取效率。在爬取网站图片时,我们需要注意下载图片的数量和下载图片的速度,可以采用异步下载的技术来解决这个问题。另外,由于该网站的图片是分页显示的,因此我们需要编写一个方法来翻页爬取。在实际开发过程中,还需要考虑一些其他因素,例如网站反爬机制、网络波动等问题。如果网站有反爬机制,我们可以采用一些反反爬的技术,例如使用代理IP、设置User-Agent等;如果网络波动导致下载失败,我们可以增加重试机制,使程序更加健壮。
完整代码奉上:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class TestCrawler {
public static void main(String[] args) {
int startPage = 1;
int endPage = 10;
for (int i = startPage; i <= endPage; i++) {
crawlPage(i);
}
}
private final static String savePath = "C:\\Users\\Administrator\\Desktop\\image\\";
private static CompletableFuture<Void> downloadImage(ImageVO imageVO) {
return CompletableFuture.runAsync(() -> {
try {
String imageUrl = imageVO.getImageUrl();
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
String fileName = imageVO.getName()+imageUrl.substring(imageUrl.lastIndexOf(".") );
File file = new File(savePath + fileName);
InputStream inputStream = conn.getInputStream();
FileOutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
inputStream.close();
outputStream.close();
System.out.println("Downloaded: " + fileName);
} else {
System.out.println("Failed to download: " + imageUrl);
}
} catch (Exception e) {
System.out.println("Failed to download: " + imageVO.getImageUrl() + ", " + e.getMessage());
}
});
}
private static void downloadImages(List<ImageVO> imageVOList) {
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (ImageVO imageVO : imageVOList) {
futures.add(downloadImage(imageVO));
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).join();
}
private static void crawlPage(int page) {
try {
String url = "http://www.cgtpw.com/ctmn/index_" + page + ".html";
Document doc = Jsoup.connect(url).get();
Elements elements = doc.select("ul.listBox2 > li > a > img");
List<ImageVO> imageUrls = new ArrayList<>();
for (Element element : elements) {
ImageVO imageVO = new ImageVO();
String imageUrl = element.attr("src");
String name = element.attr("alt");
imageVO.setName(name);
imageVO.setImageUrl(imageUrl);
imageUrls.add(imageVO);
}
downloadImages(imageUrls);
} catch (Exception e) {
System.out.println("Failed to crawl page: " + page + ", " + e.getMessage());
}
}
public static class ImageVO{
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
private String name;
private String imageUrl;
}
}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/40570.html