【Java】Java批量下载必应壁纸工具
本帖最后由 renwuqiangg 于 2018-4-25 23:07 编辑我发现这个网站的壁纸还不错 ,这些壁纸都是必应首页的背景,每天只更新一张!https://bing.ioliu.cn/ranking
如果一张一张下载太慢了,遂写了一个批量下载工具,原理也比较简单,适合初学者。输入页码,不一会儿就下载完了。只要明白了其中的原理,下载别的网站的壁纸改改相关代码就行了。
下载完后可以设置win10的背景为幻灯片,并定位到该文件夹。
只有3个类,DownloadThread.java,Msg.java,Test.java。一个jar包 :Jsoup-1.8.2.jar。
package com.ren;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class DownloadThread extends Thread {
private String filePath = "";
private String imgUrl = "";
private Msg msg;
public DownloadThread(String filePath, String imgUrl,Msg msg) {
this.filePath = filePath;
this.imgUrl = imgUrl;
this.msg = msg;
}
@Override
public void run() {
msg.addCount();
downImages(filePath, imgUrl);
}
/**
* 下载图片到指定目录
*
* @param filePath 文件路径
* @param imgUrl 图片URL
*/
public void downImages(String filePath, String imgUrl) {
// 若指定文件夹没有,则先创建
File dir = new File(filePath);
if (!dir.exists()) {
dir.mkdirs();
}
// 截取图片文件名
String fileName = imgUrl.substring(imgUrl.lastIndexOf('/') + 1, imgUrl.length());
String fileName0 = lexicalAnalysis(fileName)+".jpg";
// 写出的路径
File file = new File(filePath + File.separator + fileName0);
if(file.exists()){
System.out.println("文件已存在["+fileName+"]");
msg.addRepeat();
return ;
}
try {
URL url = new URL(imgUrl);
URLConnection connection = url.openConnection();
// 设置10秒的相应时间
connection.setConnectTimeout(10 * 1000);
InputStream in = connection.getInputStream();
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
byte[] buf = new byte;
int size;
// 写入到文件
while (-1 != (size = in.read(buf))) {
out.write(buf, 0, size);
}
out.close();
in.close();
} catch (MalformedURLException e) {
msg.addError();
e.printStackTrace();
} catch (IOException e) {
msg.addError();
e.printStackTrace();
}
msg.addSuccess();
}
//原文件名似乎含有特殊字符导致程序出错,简易的词法分析过滤一下
public static String lexicalAnalysis(String str){
StringBuffer sb = new StringBuffer();
int status = 0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9')){
if(status==0){
status=1;
sb.append(c);
}else if(status==1){
sb.append(c);
}
}else{
if(status==1){
break;
}
}
}
return sb.toString();
}
}
Msg.java主要用于记录总共下载了多少,成功了多少等
package com.ren;
public class Msg {
private int count;
private int repeat;
private int success;
private int error;
public synchronized void addCount(){
count++;
}
public synchronized void addRepeat(){
repeat++;
}
public synchronized void addSuccess(){
success++;
}
public synchronized void addError(){
error++;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "总共["+count+"],成功["+success+"],重复["+repeat+"],异常["+error+"]";
}
}
这里采用线程池,开启10个线程进行下载,但好像网速还是只有100kb/s,可能是服务器的原因吧。
package com.ren;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Test {
public static void main(String[] args) {
long start = System.currentTimeMillis();
try {
new Test().downloadBing(0,10);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("耗时:"+((end-start)/1000)+"s");
}
/**
* 必应下载榜
* @param formpage
* @param topage
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
public void downloadBing(int formpage,int topage) throws IOException, InterruptedException, ExecutionException{
String downloadUrlPre = "https://bing.ioliu.cn";
String hostUrlPre = "https://bing.ioliu.cn/ranking?p=";
String filePath = "D:/renwu/Pictures/壁纸";
Msg msg = new Msg();
ExecutorService pool =Executors.newFixedThreadPool(10);
for (int i = formpage; i < topage; i++) {
System.out.println("正在下载第["+i+"]页,url:"+hostUrlPre+i);
Document doc = Jsoup.connect(hostUrlPre+i).get();
Elements divs = doc.select("a.ctrl.download");
for (Element element : divs) {
String href = element.attr("href");
String downloadUrl = downloadUrlPre+href;
pool.submit(new DownloadThread(filePath, downloadUrl,msg));
}
}
pool.shutdown();
while(true){
if(pool.isTerminated()){
System.out.println(msg);
break;
}
Thread.sleep(1000);
}
}
}
如何运行:在eclipse新建项目,百度下载Jsoup-1.8.2.jar,加入项目的build path。新建DownloadThread.java,Msg.java,Test.java三个类并将代码复制进去,运行test即可。 mark!感谢分享 哎,小白,不懂,{:1_907:}有成品吗?{:1_908:}{:1_908:}{:1_896:} mark 一下 test.java 还没有看 回头再看 可以的,感谢分享。 原创分享,值得赞扬 楼主厉害,请问楼主JAVAse是自学的吗,感觉基础很扎实 看起来不错拿走了 多谢楼主 学习一下 本帖最后由 端木匆匆 于 2018-11-12 13:46 编辑
依葫芦画瓢做了一个,请问这个错是啥意思?
javax.net.ssl.SSLException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.readV3Record(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at sun.net.www.http.ChunkedInputStream.fastRead(Unknown Source)
at sun.net.www.http.ChunkedInputStream.read(Unknown Source)
at java.io.FilterInputStream.read(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at com.ren.DownloadThread.downImages(DownloadThread.java:58)
at com.ren.DownloadThread.run(DownloadThread.java:24)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
页:
[1]
2