记Oneplus相册爬虫无压缩文件


那年那月那时,我闲了蛋疼去刷机,于是给整机数据备份了。刷机的时候脑壳发热把数据全清了,备份的数据也没电脑备份,相册查看时每次都要同步不下载,然后官网还没有批量下载,我真想哎呦,艾瑞巴蒂在你头上暴扣,漏福来儿,我也不是爱豆。(代码与jar包文章结尾)言归正传,屁话不多说。由于能力有限,找不出官网的密码加密,所以也就不麻烦了,因为还附带了一些参数,直接登陆官网,请求相册,取到cookie。初次请求相册请求地址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
返回json,photos节点就是我们要的数据,附带图片id,和压缩过的图片地址originalPhotoUrl,smallPhotoUrl。这个originalPhotoUrl还真是女人的嘴,骗人的鬼,original是原件,原来的意思,让我以为是无压缩文件。等下载下来看文件大小才发现我就是个憨憨,不或许我就是个弟弟。待会需要这个id得到真实的地址。继续找规律发现返回的json数据中lastMatchedMoment这个数据是需要用来下次请求用的,时间节点,作为下次请求数据中的游标,还有这个参数realPhotoIndex,不晓得干嘛用的。不管他,拿他就对了。
我们继续向下滚动,还会出现listNormalPhotos这个请求,因为每次加载有限,第二次请求就要基础数据带上面的参数了。
好了,这个地方就已经获得所有图片的信息,通过json解析拿到图片id,请求真实地址。然后下载,美滋滋。请求地址:https://cloud.h2os.com/gallery/pc/getRealPhotoUrls参数:ids:=["图片id"]这个时候根据返回的数据,拿到图片无压缩地址。
ps:cookie有时效性,失效后台会爆403的错误,这个时候重新登陆网站后获取新cookie替换即可。成果:
遇到的问题:1.请求返回403,由于cookie失效导致的,好像还有浏览器标识,用火狐得到解决,之后的403都是cookie失效。2.请求无压缩地址返回500,哎,瞎了狗眼,参数用k:v,其实是k=v。纳闷的是请求图片列表时参数用的是冒号,竟然能有数据返回。3.解析json,拿到图片id。由于返回的数据是json套json数组,时间节点又不固定,取值就很烦。不过世上无难事,只怕有心人,终于还是查资料找到了。总结:真的是不想手动下载,跑来搞了这么个东西。希望也可以帮到需要这个东西的加友,一加官方你可长点心吧,同步相册竟然不下载,我们想手动下载还没有批量,我也是佛了。以下是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编码过的字节数组字符串
              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

声明:乐芙僧|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 记Oneplus相册爬虫无压缩文件


Do what I want to do