本帖最后由 AItechnology 于 2020-7-29 20:06 编辑
这次分享一个自己写的可以自定义图片主题的爬虫。
软件是由exe4j转成exe文件的,需要有java运行时环境才能运行,不过进来这个主题的看官们应该都在电脑上装java了吧。
运行效果图
运行效果
然后大家请到D:/test/下面去查看抓取结果
提取码:zqg4
提取链接:https://pan.baidu.com/s/1qc39eerU1HdIHgf0MU0joQ
更新版本:解决了爬取图片重复的bug,增加了等待时间,提高图片下载成功率
提取码:h53x
连接:https://pan.baidu.com/s/12bbmonlIDJ8lhl80nCoGcQ
下面介绍一下自己的思路:
要实现任意主题爬取,我想到的有两个思路:
1.做一个类似百度的爬虫,但这个对个人来说不现实,我们的机器怎么能和大中型计算机比
2.爬取百度的结果,拿百度拿到的图片地址直接获取。
我正是按2的思路去做,先打开百度图片网址,看如何构建Url,然后分析返回的html数据,发现在一段javascript中有解密的图片url,直接拿出来,好的,去目标地址下载图片。
下面贴核心代码:如何获取返回的字符串中的Url地址(正则表达式功力不够,自己写的一个提取工具类)
[Asm] 纯文本查看 复制代码 public static ArrayList<String> getAllUrlForBaiduImage(String doccode) {
ArrayList<String> websiteArrayList=new ArrayList<String>();//初步获取的地址,因为并不是所有地址都是图片,所以需要进一步处理
ArrayList<String> finalList=new ArrayList<String>();//最终处理完的地址
doccode=doccode.trim();//待提取的服务器返回的html字符串
int lengthForProcess=10000;//将返回的html字符串分隔为长度一万的几个段,降低处理长度
int len=doccode.length();//返回的html字符串长度
int n=len/lengthForProcess;//n代表可以分为几段
String reString="";//存储粗处理的包含url的字符串
String tmpString="";//临时存放分隔的字符串
if(n<=0) {//如果服务器返回字符串过短,则出错了
System.out.println("没有搜到结果");
finalList.add("http://pic1.win4000.com/wallpaper/2017-10-28/59f42b62ea66b.jpg");
return finalList;//返回一个默认的地址,防止异常发生
}
for(int i=1;i<n+1;i++)
{
tmpString=doccode.substring((i-1)*lengthForProcess, (i)*lengthForProcess);//取出长度为一万的子字符串
if(tmpString.contains("ObjURL")) {//粗处理,提取包含了url地址的子字符串
reString=reString+tmpString;
}
}
int lenOfStr=reString.length();
for(int i=0;i<lenOfStr;i++) {
if(i<lenOfStr-5)
if(reString.substring(i,i+4).contains("http")|reString.substring(i,i+5).contains("https")) {//在之前粗处理的字符串中找url地址
int ss=i;
while(true) {
ss=ss+1;
if(reString.substring(ss,ss+1).contains("\"")) {//在返回的字符串中,url地址都以双引号结尾
websiteArrayList.add(reString.substring(i,ss));///提取出url,但此时该url不一定是真的图片地址,可能为其他网页的地址
break;
}
if(ss>lenOfStr-5) {break;}//防止超出字符串长度的搜索
}
}
}
int sr=websiteArrayList.size();
if(sr>0) {//如果sr大于零,证明成功取出第一级url
for(int i=0;i<sr;i++) {
//过滤出真正的图片地址
if(websiteArrayList.get(i).contains("\\")|websiteArrayList.get(i).contains("ss")) {
}else if(websiteArrayList.get(i).contains("jpg")|websiteArrayList.get(i).contains("png")|websiteArrayList.get(i).contains("jpeg")) {
finalList.add(websiteArrayList.get(i));
}
}
}
sr=finalList.size();
if(sr>0) {
System.out.println("正在刷新地址,请等待");
return finalList;
}
else {
System.out.println("没有搜到结果或者已经搜索完所有结果");
finalList.add("http://pic1.win4000.com/wallpaper/2017-10-28/59f42b62ea66b.jpg");
return finalList;
}
去除重复地址的代码段:
[Asm] 纯文本查看 复制代码 ArrayList<String> finalList_refine=new ArrayList<String>();
if(sr>0) {
System.out.println("正在刷新地址,请等待");
int lenOfList=finalList.size();//提取出的图片链接数量
int tmpsize=0;//临时存放最终的图片链接数量
boolean iscontained=false;//最终
finalList_refine.add(finalList.get(0));
for(int i=1;i<lenOfList;i++) {
iscontained=false;
tmpString=finalList.get(i);
tmpsize=finalList_refine.size();
for(int j=0;j<tmpsize;j++) {
iscontained=tmpString.contains(finalList_refine.get(j));
}
if(!iscontained) {
finalList_refine.add(tmpString);
}
}//返回去除重复的链接
return finalList_refine;
|