【系列教程一】谁说 java 不能做爬虫?我第一个不服!
2023-04-25 11:09:53
先做个研究。现在传统的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.图灵?act=ctmn&cat_id=0&page=1.其中,page表示页码。我们可以通过修改page的值来获取不同页面的图片。
在了解了网站的结构后,我们可以开始编写Java程序来爬取网站的图片。
二、异步下载图片爬图时需要注意两个问题:下载图片的数量和速度。如果一次下载大量图片,会占用太多的内存和网络带宽,导致程序运行缓慢。此外,如果下载速度太慢,也会影响程序的运行效率。因此,我们需要使用异步下载技术来解决这个问题。
Java提供了各种异步下载图片的方法,如使用线程池和Java CompletableFuture等。本文将介绍Java的使用 Completablefuture在8中异步下载图片。
首先,我们需要创建一种下载图片的方法。该方法以图片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.图灵?act=ctmn&cat_id=0&page=" + page; Document doc = Jsoup.connect(url).get(); Elements elements = doc.select("p.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爬取网站图片的过程,并采用异步下载和翻页爬取技术,提高爬取效率。爬网站图片时,需要注意下载图片的数量和速度,可以采用异步下载技术来解决这个问题。另外,由于网站的图片是分页显示的,所以我们需要编写一种翻页爬行的方法。在实际开发过程中,还需要考虑网站反爬机制、网络波等其他因素移动和其他问题。如果网站有反爬机制,我们可以使用一些反爬技术,如使用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; }}