`

qq album

    博客分类:
  • j2ee
 
阅读更多
此文章完全转自他人博客(用于个人学习记录)
这个功能的实现关键在于找到每张图片的链接地址,之前一直不知道怎么找到,后来发现用SmartSniff分析数据包,很容易就找到了
/**
 * core class
 * 
 * @author wensefu.jerry.Ling<br/>
 *         wrote on 2011-1-28
 */
public class PhotoDownLoad {
 /*
  * sample uri: album:
  * http://xalist.photo.qq.com/fcgi-bin/fcg_list_album?uin=
  * 419758768&outstyle=2&t=0.7253889227680141&g_tk=5381 photo:
  * http://xaplist.
  * photo.qq.com/fcgi-bin/fcg_list_photo?uin=419758768&albumid=
  * e3b63b1c-2dce-4f86-ad02-c0f81a878615
  * &outstyle=json&t=0.9962191131376609&g_tk=5381
  */
 private static final String albumbase = "http://xalist.photo.qq.com/fcgi-bin/fcg_list_album?uin=";
 private static final String photobase = "http://xaplist.photo.qq.com/fcgi-bin/fcg_list_photo?uin=";
 private static final String charset = "gb2312";
 private static List<Album> albums; // 获取的所有相册
 private static final String savePath = "e://qqPhoto//"; // 图片保存位置的父目录
 private int curIndex = 0; // 每个相册当前正在下载的图片指针
 /**
  * 获取用户相册
  * 
  * @param qq
  * @return
  */
 public List<Album> getAlbums(String qq) {
  List<Album> result = new ArrayList<Album>();
  HttpClient client = new HttpClient();
  String getUri = albumbase + qq + "&outstyle=2"; // outstyle!=2服务器将以xml的形式返回结果,
              // 这里只以简单文本解析提取相关信息,不做xml解析了.
  HttpMethod method = new GetMethod(getUri);
  method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,
    charset);
  int status = 0;
  try {
   status = client.executeMethod(method);
   if (status != HttpStatus.SC_OK) {
    System.err.println("发生网络错误!");
    return null;
   }
  } catch (HttpException e) {
   e.printStackTrace();
   return null;
  } catch (IOException e) {
   e.printStackTrace();
   return null;
  }
  InputStream is = null;
  BufferedReader br = null;
  InputStreamReader isr = null;
  List<String> ids = new ArrayList<String>();
  List<String> names = new ArrayList<String>();
  List<Integer> totals = new ArrayList<Integer>();
  try {
   is = method.getResponseBodyAsStream();
   isr = new InputStreamReader(is);
   br = new BufferedReader(isr);
   String temp = null;
   while ((temp = br.readLine()) != null) {
    if (temp.contains("/"id/" :")) {
     String id = temp.substring(temp.indexOf("/"id/" :") + 8,
       temp.length() - 2);
     ids.add(id);
    }
    if (temp.contains("/"name/" :")) {
     String name = temp.substring(
       temp.indexOf("/"name/" :") + 10, temp.length() - 3);
     names.add(name);
    }
    if (temp.contains("/"total/" :")) {
     String total = temp
       .substring(temp.indexOf("/"total/" :") + 10,
         temp.length() - 1);
     totals.add(Integer.parseInt(total));
    }
    if (temp.contains("/"left/" :")) {
     break;
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   method.releaseConnection();
   try {
    br.close();
    isr.close();
    is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  for (int i = 0; i < ids.size(); i++) {
   Album album = new Album(ids.get(i), names.get(i), totals.get(i));
   result.add(album);
  }
  return result;
 }
 /**
  * 获取一个相册的图片信息
  * 
  * @param pid
  * @return
  */
 public List<Photo> getPhotoByAlbum(Album album, String qq) {
  List<Photo> result = new ArrayList<Photo>();
  HttpClient client = new HttpClient();
  System.out.println(album.getId());
  String getUri = photobase + qq + "&albumid=" + album.getId()
    + "&outstyle=json";
  HttpMethod method = new GetMethod(getUri);
  method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,
    charset);
  int status = 0;
  try {
   status = client.executeMethod(method);
   if (status != HttpStatus.SC_OK) {
    System.err.println("发生网络错误!");
    return null;
   }
  } catch (HttpException e) {
   e.printStackTrace();
   return null;
  } catch (IOException e) {
   e.printStackTrace();
   return null;
  }
  InputStream is = null;
  BufferedReader br = null;
  InputStreamReader isr = null;
  List<String> names = new ArrayList<String>();
  List<String> urls = new ArrayList<String>();
  try {
   is = method.getResponseBodyAsStream();
   isr = new InputStreamReader(is);
   br = new BufferedReader(isr);
   String temp = null;
   boolean sign = false;
   while ((temp = br.readLine()) != null) {
    int len = temp.length();
    if (temp.contains("/"pic/" : [")) {
     sign = true;
    }
    if (sign && temp.contains("/"name/" :")) {
     String name = temp.substring(
       temp.indexOf("/"name/" :") + 10, len - 2);
     names.add(name);
    }
    if (temp.contains("/"url/" :")) {
     String url = temp.substring(temp.indexOf("/"url/" :") + 9,
       len - 3);
     urls.add(url);
    }
    if (temp.contains(" ],")) {
     break;
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   method.releaseConnection();
   try {
    br.close();
    isr.close();
    is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  for (int i = 0; i < names.size(); i++) {
   Photo photo = new Photo();
   photo.setName(names.get(i));
   photo.setUrl(urls.get(i));
   photo.setAlbum(album);
   result.add(photo);
  }
  return result;
 }
 /**
  * 通过uri下载远程图片到本地
  * 
  * @param uri
  * @param name
  *            要保存的图片名(非路径)
  */
 public void saveImgFromUrl(Photo photo, String qq) {
  URL imgurl = null;
  BufferedInputStream bis = null;
  OutputStream os = null;
  try {
   imgurl = new URL(photo.getUrl());
   bis = new BufferedInputStream(imgurl.openStream());
   byte[] buffer = new byte[512];
   File path = new File(savePath + "//" + qq + "//"
     + photo.getAlbum().getName().trim());
   if (!path.exists()) {
    path.mkdirs();
   }
   os = new FileOutputStream(new File(path, photo.getName().trim()
     + ".jpeg"));
   int len = 0;
   while ((len = bis.read(buffer)) > 0) {
    os.write(buffer, 0, len);
   }
  } catch (MalformedURLException e) {
   e.printStackTrace();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   try {
    bis.close();
    os.flush();
    os.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 /**
  * 下载一个相册的图片
  * 
  * @param index
  *            相册序号
  */
 public void savePhoto(final int index, final String qq) {
  Album album = albums.get(index);
  final List<Photo> photos = this.getPhotoByAlbum(album, qq);
  if (photos == null || photos.size() == 0) {
   System.out.println("相册" + album.getName() + "为空.");
   return;
  }
  final int maxThreadCnt = 10; // 每个相册最多开启10个线程进行下载
  final int total = album.getCnt();
  int realThreadCnt = total >= maxThreadCnt ? maxThreadCnt : total; // 实际下载一个相册的线程数
  /**
   * 线程驱动下载任务
   * 
   * @author wensefu.jerry.Ling<br/>
   *         wrote on 2011-1-29
   */
  class DownLoadTask implements Runnable {
   int id; // 线程标识
   int pindex;// 下载的图片指针
   public DownLoadTask(int id, int pindex) {
    this.id = id;
    this.pindex = pindex;
   }
   @Override
   public void run() {
    while (curIndex <= total - 1) {
     int temp = pindex;
     pindex = curIndex;
     curIndex++;
     Photo photo = photos.get(temp);
     System.out.println("线程" + (index + 1) + "_" + id + "开始下载第"
       + (index + 1) + "个相册第" + (pindex + 1) + "张图片...");
     saveImgFromUrl(photo, qq);
     System.out.println("线程" + (index + 1) + "_" + id + "完成第"
       + (index + 1) + "个相册第" + (pindex + 1) + "张图片下载");
    }
   }
  }
  ExecutorService exec = Executors.newCachedThreadPool();
  /*
   * 初始化各线程状态 此处给每个线程分配一个下载起始点
   */
  for (int i = 0; i < realThreadCnt; i++) {
   DownLoadTask task = new DownLoadTask(i + 1, i);
   exec.execute(task);
  }
  exec.shutdown();
 }
 public static void main(String[] args) {
  PhotoDownLoad pdl = new PhotoDownLoad();
  String qq = "402493283";
  albums = pdl.getAlbums(qq);
  if (albums == null || albums.size() == 0) {
   System.err.println("相册信息获取失败,可能是用户没有开放权限.");
   return;
  }
  int len = albums.size();
  System.out.println("相册信息获取成功,用户共有" + len + "个相册.");
  for (int i = 0; i < len; i++) { // 考虑到相册数量不会很多,相册采用顺序下载,不使用异步下载
   System.out.println("开始下载第" + (i + 1) + "个相册...");
   pdl.savePhoto(i, qq);
   pdl.curIndex = 0;
   System.out.println("第" + (i + 1) + "个相册下载完成.");
  }
 }
}





 

/**
 * 图片实体类
 * 
 * @author wensefu.jerry.Ling<br/>
 *         wrote on 2011-1-28
 */
public class Photo {
	private Album album;
	private String url;
	private String name;
	//getter and setter
         ....
}

/**
 * 相册实体类
 * 
 * @author wensefu.jerry.Ling<br/>
 *         wrote on 2011-1-28
 */
public class Album {
	private String id;
	private String name;
	private int cnt; // 图片张数
	public Album() {
	}
	/**
	 * @param id
	 * @param name
	 * @param cnt
	 */
	public Album(String id, String name, int cnt) {
		super();
		this.id = id;
		this.name = name;
		this.cnt = cnt;
	}
	//getter and setter
         ....
}

 

 

分享到:
评论

相关推荐

    ios-QQ相册.zip

    仿造QQ相册进行封装了一个,里面能满足创建相册 展示相册等。并且将之前的AlertView进行完善,并且可以进行正常使用 github 网址 :https://github.com/gdhGaoFei/GF_QQPhotos 欢迎大家一起探讨 QQ:1043902770

    QQ登陆接口

    - **添加相册接口**:`https://graph.qq.com/photo/add_album` - **上传图片接口**:`https://graph.qq.com/photo/upload_pic` 每个接口都有其特定的参数要求和返回格式,开发者需参照官方文档进行调用。 #### 四...

    QQ空间相册POST上传

    xhr.open('POST', 'http://qzone.qq.com/album/upload'); xhr.setRequestHeader('Content-Type', 'multipart/form-data'); // 上传文件需设置此头 xhr.onreadystatechange = function() { if (xhr.readyState === 4...

    一个模仿QQ相册效果演示

    例如,可以使用类选择器 `.album` 来选取所有的相册元素,然后使用 `.each()` 函数遍历并操作它们。在相册中,图片通常被组织成网格布局,这可以通过CSS的`display: inline-block`或`flexbox`实现,而jQuery可以帮助...

    仿QQ相册-图片上的左右箭头js代码

    在开发Web应用时,我们经常会遇到需要实现类似QQ相册这样的图片浏览功能,其中涉及到关键的交互元素就是图片切换时的左右箭头。这个功能主要依赖JavaScript(JS)来实现,因为JavaScript能提供动态交互和实时响应...

    C#仿QQ空间个人站点(.NET+SQL)_WebZone

    http://download.csdn.net/user/cleopard/album @更多@ http://cleopard.download.csdn.net/ 福利 http://xuemeilaile.com 17份软件测试文档 http://download.csdn.net/album/detail/1425 13份WPF经典开发教程 ...

    An album of fluid motion

    关于流体计算的一些详细的资料、程序和图片,个人感觉不错,所以拿来分享

    流体图册1-An_Album_Of_Fluid_Motion-1.pdf

    与流体光学等其他领域的同事一样,从事流体力学工作的人也很幸运,主题很容易可视化。流量可视化从早期开始就在研究中发挥了重要作用,总是产生定性见解,最近还产生了定量结果。在本世纪的流体力学文学中散布着许多...

    Android代码-QQ相册选择风格的图片选择器,高效,低耗,响应快速。

    Support singleSelection, Multiselect, photo preview,scalable ,sliding to quit preview,QQ pick style. Getting Started Gradle dependencies { compile 'com.library.tangxiaolv:telegramgallery:1.0.5' }...

    jQuery QQ空间浏览相册

    $(".albumImage").on("click", function() { // 在这里处理点击事件,如显示大图或预览 }); ``` 动画效果是jQuery的一大亮点。在QQ空间相册浏览中,可能会有淡入淡出、滑动等过渡效果。jQuery的`.fadeIn()`, `....

    ImageChooser-Android 仿QQ图片选择器,包含图片裁剪,浏览大图功能。.zip

    Android 仿QQ图片选择器,包含图片裁剪,浏览大图功能。 博客地址:http://blog.csdn.net/junzia/article/details/53091606简单使用示例如需使用图片选择器功能,将chooser加入为依赖工程,然后使用指定功能:选择...

    基于知识共享的算法附matlab代码.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    基于群体稀疏学习方法的轴承故障诊断matlab源码.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    【LSTM时序预测】基于LSTM和BiLSTM实现时间序列预测附matlab代码.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    基于Matlab模拟中性景观生成器.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    基于Matlab模拟四连杆机器人.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    改进的快速排序查找多目标优化算法附matlab源码.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    基于深度学习算法和浅层学习算法进行缺失值预测附matlab代码.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    基于贝叶斯过滤器模拟一个简单的机器人在地图上定位附matlab代码.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

    基于Matlab设计天线方向图阵列.zip

    擅长[智能优化算法](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzU3ODU5OA==&action=getalbum&album_id=2089545783208394752#wechat_redirect)、[神经网络预测]...)、[信号处理]...

Global site tag (gtag.js) - Google Analytics