AItechnology 发表于 2020-7-29 16:20

可以抓取自定义图片主题的爬虫

本帖最后由 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地址(正则表达式功力不够,自己写的一个提取工具类)

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;
            }

去除重复地址的代码段:
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;

AItechnology 发表于 2020-7-31 22:14

tonybrook 发表于 2020-7-29 17:06
这个主要是用于技术学习的,不能用于实际中的。

重复抓取的问题已经解决,请看后面我回复中分享的地址。

祝大家新年快乐 发表于 2020-7-29 17:11

试了下,非常的不错!!
两个小问题:有部分图片会出现“文件传输出现错误”,试了下10页,还有一些重叠的照片哦。
非常感谢楼主分享,{:17_1069:}

南归不NG 发表于 2020-7-29 16:33

我真没装java

绫音 发表于 2020-7-29 16:41

电脑需要java环境才能使用吗

a6243116q 发表于 2020-7-29 16:48

支持谢谢分享

飘零007 发表于 2020-7-29 16:49

我也没装,表示装了java环境变量,不行,已放弃{:1_937:}

皖东赵日天 发表于 2020-7-29 16:57

啥也看不懂啊。。。

Ldw 发表于 2020-7-29 16:58

感谢楼主分享

墨玉_Jade 发表于 2020-7-29 17:04

感谢分享

tonybrook 发表于 2020-7-29 17:06

这个主要是用于技术学习的,不能用于实际中的。
页: [1] 2
查看完整版本: 可以抓取自定义图片主题的爬虫