您建议的方法存在一些问题:
您正在尝试使用 JSoup 下载文件内容数据... JSoup 仅适用于文本数据,但不会返回图像内容/值。要下载图像内容,您需要一个 HTTP 请求
要下载图像,您还需要复制将通过浏览器发出的请求。您可以打开 Chrome,打开开发者工具并打开网络标签。输入您要从中抓取图像的页面的 URL,您会看到正在发出的一堆请求。视图中某处的每个图像都会有一个单独的请求...如果您单击标记为的那个,1.jpg
您将看到下载第一个图像的请求,然后您需要复制所有用于请求该图像。您会注意到,请求和响应标头显示在此视图中。成功复制请求后,您就可以开始测试需要哪些标头/cookie。我发现唯一真正的要求是“referer”标头是必要的。
我已经删除了您可能需要/想要的大部分内容,但类似于下面的内容是您所追求的。我已经以全部质量完整地提取了漫画书图像。我引入了一个小型睡眠计时器,以免服务器过载,因为有时您会受到速率限制。即使没有它,您也应该没问题,但您不想被阻止很长一段时间,因此您可以让请求返回给您的速度越慢越好。您甚至可以并行提出请求。
我几乎可以肯定,你可以在下面的一些代码上减少更多,以获得更清晰的结果......但它有效,我假设这已经足够了。
有趣的问题。
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.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
public class JSoupExample {
private static int TIMEOUT = 30000;
private static final int BUFFER_SIZE = 4096;
public static void main(String... args) throws InterruptedException, IOException {
String url = "https://manganelo.com/chapter/read_bleach_manga_online_for_free2/chapter_686";
Document doc = Jsoup.connect(url).get();
// Select only urls where the source starts with the relevant url (not all images)
Elements media = doc.select("img[src^=\"https://s5.mkklcdnv5.com/mangakakalot/r1/read_bleach_manga_online_for_free2/chapter_686_death_and_strawberry/\"]");
Iterator<Element> ie = media.iterator();
int i = 1;
while (ie.hasNext()) {
String imageUrlString = ie.next().attr("src");
System.out.println(imageUrlString + " ");
try {
HttpURLConnection response = makeImageRequest(url, imageUrlString);
if (response.getResponseCode() == 200) {
writeToFile(i, response);
}
} catch (IOException e) {
// skip file and move to next if unavailable
e.printStackTrace();
System.out.println("Unable to download file: " + imageUrlString);
}
i++; // increment image ID whatever the result of the request.
Thread.sleep(200l); // prevent yourself from being blocked due to rate limiting
}
}
private static void writeToFile(int i, HttpURLConnection response) throws IOException {
// opens input stream from the HTTP connection
InputStream inputStream = response.getInputStream();
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream("image_" + i + ".jpg");
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
}
private static HttpURLConnection makeImageRequest(String referer, String imageUrlString) throws IOException {
URL imageUrl = new URL(imageUrlString);
HttpURLConnection response = (HttpURLConnection) imageUrl.openConnection();
response.setRequestMethod("GET");
response.setRequestProperty("referer", referer);
response.setConnectTimeout(TIMEOUT);
response.setReadTimeout(TIMEOUT);
response.connect();
return response;
}
}
我还想确保根据内容类型设置正确的文件扩展名,因为我相信有些是以.png
格式而不是.jpeg
. 我也相当确定写入文件可以被清理得更简单/更清晰,而不是读取字节流。