在網上找過相關的資料,都不是太全~有些缺漏。全部本身根據網上的再結合本身的修改了下。java
1.經過HttpAnalyzerStdV5 分析QQ空間相冊的真實地址。一下就是空間相冊的地址:服務器
以前在網上看見只有一個地址,可是經過個人分析,貌似會有很大的問題。好比:某我的的空間相冊有些是有設置密碼的。也有不設置密碼的,那麼就沒法下載。由於這類的相冊是經過另一個URL解析的。網絡
private static final String albumbase1 = "http://alist.photo.qq.com/fcgi-bin/fcg_list_album?uin=";//若是沒有設置密保的相冊是經過這個地址訪問的 private static final String albumbase2 = "http://xalist.photo.qq.com/fcgi-bin/fcg_list_album?uin=";//設置密保的相冊是經過這個地址訪問的 //private static final String photobase = "http://alist.photo.qq.com/fcgi-bin/fcg_list_photo?uin="; private static final String photobase1 = "http://plist.photo.qq.com/fcgi-bin/fcg_list_photo?uin="; private static final String photobase2 = "http://xaplist.photo.qq.com/fcgi-bin/fcg_list_photo?uin=";
2.程序的main方法:異步
1.albums集合是全部相冊的集合。ui
2.主要是兩個方法一個是獲得集合getAlbums 一個是保存相冊的 savePhotothis
public static void main(String[] args) { PhotoDownLoad pdl = new PhotoDownLoad(); String qq = "1315404564"; albums = pdl.getAlbums(qq, albumbase1);//先傳一個地址進去要是找到再也不分析另一個地址 if (albums == null || albums.size() == 0) { albums = pdl.getAlbums(qq, albumbase2); } if (albums == null || albums.size() == 0) { System.out.println("沒有獲取到相冊"); } 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) + "個相冊下載完成."); } }
3.getAlbums 方法
1.url
/** * 獲取用戶相冊 * * @param qq * @return */ public List<Album> getAlbums(String qq, String url) { List<Album> result = new ArrayList<Album>(); HttpClient client = new HttpClient(); String getUri = url + qq + "&outstyle=2"; // outstyle!=2服務器將以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; }
4.下載一個相冊。.net
1.獲得一個相冊的整個圖片。線程
/** * 下載一個相冊的圖片 * * @param index 相冊序號 */ public void savePhoto(final int index, final String qq) { Album album = albums.get(index); if(album.getName().indexOf("微博")>=0){ System.out.println("微博相冊不下載"); return; } List<Photo> photosTemp = this.getPhotoByAlbum(album, qq, photobase1); if (photosTemp == null || photosTemp.size() == 0) { photosTemp = this.getPhotoByAlbum(album, qq, photobase2); } if (photosTemp == null || photosTemp.size() == 0) { System.out.println("相冊信息爲空"); return; } else { final List<Photo> photos = photosTemp; 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; } 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(); } }
源代碼下載:http://www.oschina.net/code/snippet_557580_12818