那年那月那时,我闲了蛋疼去刷机,于是给整机数据备份了。刷机的时候脑壳发热把数据全清了,备份的数据也没电脑备份,相册查看时每次都要同步不下载,然后官网还没有批量下载,我真想哎呦,艾瑞巴蒂在你头上暴扣,漏福来儿,我也不是爱豆。(代码与jar包文章结尾)

言归正传,屁话不多说。由于能力有限,找不出官网的密码加密,所以也就不麻烦了,因为还附带了一些参数,直接登陆官网,请求相册,取到cookie。

Image

初次请求相册

请求地址https://cloud.h2os.com/gallery/pc/listNormalPhotos

请求参数:size=100&state=active&smallPhotoScaleParams=image/resize,m_mfit,h_250,w_250&originalPhotoScaleParams=image/resize,m_mfit,h_1300,w_1300

Image

返回json,photos节点就是我们要的数据,附带图片id,和压缩过的图片地址originalPhotoUrl,smallPhotoUrl。这个originalPhotoUrl还真是女人的嘴,骗人的鬼,original是原件,原来的意思,让我以为是无压缩文件。等下载下来看文件大小才发现我就是个憨憨,不或许我就是个弟弟。待会需要这个id得到真实的地址。

继续找规律发现返回的json数据中lastMatchedMoment这个数据是需要用来下次请求用的,时间节点,作为下次请求数据中的游标,还有这个参数realPhotoIndex,不晓得干嘛用的。不管他,拿他就对了。

Image

我们继续向下滚动,还会出现listNormalPhotos这个请求,因为每次加载有限,第二次请求就要基础数据带上面的参数了。

Image

好了,这个地方就已经获得所有图片的信息,通过json解析拿到图片id,请求真实地址。然后下载,美滋滋。

请求地址:https://cloud.h2os.com/gallery/pc/getRealPhotoUrls

参数:ids:=["图片id"]

这个时候根据返回的数据,拿到图片无压缩地址。

Image

ps:cookie有时效性,失效后台会爆403的错误,这个时候重新登陆网站后获取新cookie替换即可。

成果:

Image

遇到的问题:

1.请求返回403,由于cookie失效导致的,好像还有浏览器标识,用火狐得到解决,之后的403都是cookie失效。

2.请求无压缩地址返回500,哎,瞎了狗眼,参数用k:v,其实是k=v。纳闷的是请求图片列表时参数用的是冒号,竟然能有数据返回。

3.解析json,拿到图片id。由于返回的数据是json套json数组,时间节点又不固定,取值就很烦,可把我累坏了,本来基础就差,刚玩java。不过世上无难事,只怕有心人,终于还是查资料找到了。

总结:真的是不想手动下载,跑来搞了这么个东西。希望也可以帮到需要这个东西的加友,一加官方你可长点心吧,同步相册竟然不下载,我们想手动下载还没有批量,我也是佛了。

以下是java代码(你们只需要替换cookie和保存路径):

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import sun.misc.BASE64Encoder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**  

 * <p>Title: Test.java</p>  

 * <p>Description:Oneplus相册爬虫(无压缩) </p>  

 * <p>Company: www.zhguo.vip</p>  

 * @author zhenghuiguo 

 * @date 2019-8-23  

 * @version 1.0  
  
 * Readme:请在官网登录https://cloud.h2os.com,点击相册,请求后拿到cookie替换到本程序cookie。

 */


public class Test {


	public static void main(String[] args) throws  Exception{
		int count=0;
		  ArrayList<String> arr= new ArrayList<String>();
		   Map<String, String> hashmap=new HashMap<String, String>();
		//文件保存路径
		String saveImgPath="C://Users//zhg//Desktop//img//";
        //获取相册列表
		//cursor=20190822&photoIndex=1
		//lastMatchedMoment   realPhotoIndex
		//初始化数据
		String data="size=100&state=active&smallPhotoScaleParams=image/resize,m_mfit,h_250,w_250&originalPhotoScaleParams=image/resize,m_mfit,h_1300,w_1300";
        String urlpath="https://cloud.h2os.com/gallery/pc/listNormalPhotos";
        String cookie="此处需要替换";
        while(true){
        //post请求得到json数据
        String postServer = PostServer(data, urlpath, cookie);
        //重置data基础数据
        data="size=100&state=active&smallPhotoScaleParams=image/resize,m_mfit,h_250,w_250&originalPhotoScaleParams=image/resize,m_mfit,h_1300,w_1300";
        System.out.println("postServer"+"======"+postServer);
        JSONObject jobj = JSON.parseObject(postServer);
        System.out.println("下一个时间段"+jobj.getString("lastMatchedMoment")+"....."+"下一个index"+jobj.getString("realPhotoIndex"));
        //获取下一页游标
        String lastMatchedMoment=(jobj.getString("lastMatchedMoment"))== null?null:jobj.getString("lastMatchedMoment");
        String photoIndex=(jobj.getString("realPhotoIndex"))== null?null:jobj.getString("realPhotoIndex");
        //判断下一页是否有值
        if(lastMatchedMoment!=null&&!"".equals(lastMatchedMoment)&&photoIndex!=null&&!"".equals(photoIndex)){
        	data=data+"&cursor="+lastMatchedMoment+"&photoIndex="+photoIndex;
        }
        //System.out.println("name"+jobj.get("photos"));
      //拿到photos节点
      JSONObject photosjson = jobj.getJSONObject("photos");
      //将photosjson赋值给map1,便于后面遍历时间节点。由于时间节点不固定,无法准确拿到json数据。
      Map map1 = photosjson; 
      //遍历出key值存入arr
      for (Object o : map1.entrySet()) { 
              Map.Entry<String,JSONArray> entry = (Map.Entry<String,JSONArray>)o; 
              arr.add(entry.getKey());
      } 
      //遍历每个时间节点的值
      for (int i = 0; i < arr.size(); i++) {
			JSONArray photos = photosjson.getJSONArray(arr.get(i));
			//遍历每个时间节点下的多个照片
			for (int j = 0; j < photos.size(); j++) {
				JSONObject phototimeJson = (JSONObject) photos.get(j);
				String title=phototimeJson.getString("title");
				//得到图片id,存入hashmap<"title","id">
				String img_id=phototimeJson.getString("id");
				hashmap.put(title, img_id);
			}
    	
      }
        for(String key : hashmap.keySet()){
        	String realPathJson = Downimg.getRealPath(hashmap.get(key), cookie);
        	JSONObject j=JSONObject.parseObject(realPathJson);
        	String  realPath = j.getString(hashmap.get(key));
        	Downimg.downloadPicture(realPath, saveImgPath+key);
        	count++;
        }
        if(lastMatchedMoment.equals("EOF")){
        	System.out.println("下载完成"+">>>>>文件个数:"+count+"个");
        	return ;
        }
        //清空数据
        map1.clear();
        hashmap.clear();
        arr.clear();
        System.out.println("清空完成");
       }	
	}
 
  //Post请求
  		public static String PostServer(String data,String urlpath,String cookie){
  				PrintWriter out = null;
  		        BufferedReader is = null;
  		        String result = "";
  			try {
  	            URL url = new URL(urlpath);
  	            //打开和url之间的连接
  	            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  	            conn.setRequestProperty("accept", "*/*");
  	            conn.setRequestProperty("connection", "Keep-Alive");
  	            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0");
  	            conn.setRequestProperty("Host", "cloud.h2os.com");
  	            conn.setRequestProperty("referer", "https://cloud.h2os.com/");
  	            conn.setRequestProperty("Cookie", cookie);
  	            conn.setRequestMethod("POST");//GET和POST必须全大写
  	            conn.setDoOutput(true);
  	            conn.setDoInput(true);
  	            out = new PrintWriter(conn.getOutputStream());//获取URLConnection对象对应的输出流 
  	            out.print(data);//发送请求参数即数据
  	            out.flush();//缓冲数据
  	         // 定义BufferedReader输入流来读取URL的响应
  	            is = new BufferedReader(
  	                    new InputStreamReader(conn.getInputStream()));
  	            String line;
  	            while ((line = is.readLine()) != null) {
  	                result += line;
  	            }
  	        } catch (Exception e) {
  	            System.out.println("发送 POST 请求出现异常!"+e);
  	            e.printStackTrace();
  	        }
  	        finally{
  	            try{
  	                if(out!=null){
  	                    out.close();
  	                }
  	                if(is!=null){
  	                    is.close();
  	                }
  	            }
  	            catch(IOException ex){
  	                ex.printStackTrace();
  	            }
  	        }
  	        return result;
  	    }    
  			
  		
  		 //根据id得到无压缩图片地址
  		 public static String getRealPath(String Imgid,String cookie){
  			 String urlpath="https://cloud.h2os.com/gallery/pc/getRealPhotoUrls";
  			 String data="ids=[\""+Imgid+"\"]";
//  			 System.out.println("imgId"+"====="+data);
  			 String realImgPath = PostServer(data, urlpath, cookie);
  			 return realImgPath;
  		 }
  		 //链接url下载图片
  	    public static void downloadPicture(String urlPath,String savePath) {
  	        URL url = null;
  	        try {
  	            url = new URL(urlPath);
  	            DataInputStream dataInputStream = new DataInputStream(url.openStream());
  	            File file=new File(savePath);
  	            if(!file.exists()){
  	            FileOutputStream fileOutputStream = new FileOutputStream(file);
  	           
  	            ByteArrayOutputStream output = new ByteArrayOutputStream();

  	            byte[] buffer = new byte[1024];
  	            int length;

  	            while ((length = dataInputStream.read(buffer)) > 0) {
  	                output.write(buffer, 0, length);
  	            }
  	            BASE64Encoder encoder = new BASE64Encoder();
  	            String encode = encoder.encode(buffer);//返回Base64编码过的字节数组字符串
//  	            System.out.println(encode);
  	            fileOutputStream.write(output.toByteArray());
  	            dataInputStream.close();
  	            fileOutputStream.close();
  	            }else{
  	            	System.out.println("文件已存在");
  	            }
  	        } catch (MalformedURLException e) {
  	            e.printStackTrace();
  	        } catch (IOException e) {
  	            e.printStackTrace();
  	        }
  	        
  	    }
}

jar包下载地址:https://cloud.189.cn/t/Nvi2uanANRzu(访问码:zs99)

运行后直接浏览器打开:localhost,填写cookie使用。

帮助到你了,请帮我点个star哦!https://github.com/Khada-Jhin8/oneplus-cloudphotos

最后修改:2022 年 07 月 16 日
如果觉得我的文章对你有用,请随意赞赏