在网上找过相关的资料,都不是太全~有些缺漏。所有自己根据网上的再结合自己的修改了下。
1.通过HttpAnalyzerStdV5 分析QQ空间相册的真实地址。一下就是空间相册的地址:
之前在网上看见只有一个地址,但是通过我的分析,貌似会有很大的问题。比如:某个人的空间相册有些是有设置密码的。也有不设置密码的,那么就无法下载。因为这类的相册是通过另外一个URL解析的。
1 | private static final String albumbase1 = "http://alist.photo.qq.com/fcgi-bin/fcg_list_album?uin=" ;//如果没有设置密保的相册是通过这个地址访问的 |
2 | private static final String albumbase2 = "http://xalist.photo.qq.com/fcgi-bin/fcg_list_album?uin=" ;//设置密保的相册是通过这个地址访问的 |
3 |
4 | //private static final String photobase = "http://alist.photo.qq.com/fcgi-bin/fcg_list_photo?uin="; |
5 | private static final String photobase1 = "http://plist.photo.qq.com/fcgi-bin/fcg_list_photo?uin=" ; |
6 | private static final String photobase2 = "http://xaplist.photo.qq.com/fcgi-bin/fcg_list_photo?uin=" ; |
2.程序的main方法:
1.albums集合是所有相册的集合。
2.主要是两个方法一个是得到集合getAlbums 一个是保存相册的 savePhoto
01 | public static void main(String[] args) { |
02 | PhotoDownLoad pdl = new PhotoDownLoad(); |
03 | String qq = "1315404564" ; |
04 | albums = pdl.getAlbums(qq, albumbase1); //先传一个地址进去要是找到不再分析另外一个地址 |
05 | if (albums == null || albums.size() == 0 ) { |
06 | albums = pdl.getAlbums(qq, albumbase2); |
07 | } |
08 | if (albums == null || albums.size() == 0 ) { |
09 | System.out.println( "没有获取到相册" ); |
10 | } |
11 | int len = albums.size(); |
12 | System.out.println( "相册信息获取成功,用户共有" + len + "个相册." ); |
13 | for ( int i = 0 ; i < len; i++) { // 考虑到相册数量不会很多,相册采用顺序下载,不使用异步下载 |
14 | System.out.println( "开始下载第" + (i + 1 ) + "个相册..." ); |
15 | pdl.savePhoto(i, qq); |
16 | pdl.curIndex = 0 ; |
17 | System.out.println( "第" + (i + 1 ) + "个相册下载完成." ); |
18 | } |
19 | } |
3.getAlbums 方法
1.
01 | /** |
02 | * 获取用户相册 |
03 | * |
04 | * @param qq |
05 | * <a href="http://my.oschina.net/u/556800" target="_blank" rel="nofollow">@return</a> |
06 | */ |
07 | public List<Album> getAlbums(String qq, String url) { |
08 | List<Album> result = new ArrayList<Album>(); |
09 | HttpClient client = new HttpClient(); |
10 | String getUri = url + qq + "&outstyle=2" ; // outstyle!=2服务器将以xml的形式返回结果, |
11 | HttpMethod method = new GetMethod(getUri); |
12 | method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, |
13 | charset); |
14 | int status = 0 ; |
15 | try { |
16 | status = client.executeMethod(method); |
17 | if (status != HttpStatus.SC_OK) { |
18 | System.err.println( "发生网络错误!" ); |
19 | return null ; |
20 | } |
21 | } catch (HttpException e) { |
22 | e.printStackTrace(); |
23 | return null ; |
24 | } catch (IOException e) { |
25 | e.printStackTrace(); |
26 | return null ; |
27 | } |
28 | InputStream is = null ; |
29 | BufferedReader br = null ; |
30 | InputStreamReader isr = null ; |
31 | List<String> ids = new ArrayList<String>(); |
32 | List<String> names = new ArrayList<String>(); |
33 | List<Integer> totals = new ArrayList<Integer>(); |
34 | try { |
35 | is = method.getResponseBodyAsStream(); |
36 | isr = new InputStreamReader(is); |
37 | br = new BufferedReader(isr); |
38 | String temp = null ; |
39 | while ((temp = br.readLine()) != null ) { |
40 | if (temp.contains( "\"id\" :" )) { |
41 | String id = temp.substring(temp.indexOf( "\"id\" :" ) + 8 , |
42 | temp.length() - 2 ); |
43 | ids.add(id); |
44 | } |
45 | if (temp.contains( "\"name\" :" )) { |
46 | String name = temp.substring( |
47 | temp.indexOf( "\"name\" :" ) + 10 , temp.length() - 3 ); |
48 | names.add(name); |
49 | } |
50 | if (temp.contains( "\"total\" :" )) { |
51 | String total = temp |
52 | .substring(temp.indexOf( "\"total\" :" ) + 10 , |
53 | temp.length() - 1 ); |
54 | totals.add(Integer.parseInt(total)); |
55 | } |
56 | if (temp.contains( "\"left\" :" )) { |
57 | break ; |
58 | } |
59 | } |
60 | } catch (IOException e) { |
61 | e.printStackTrace(); |
62 | } finally { |
63 | method.releaseConnection(); |
64 | try { |
65 | br.close(); |
66 | isr.close(); |
67 | is.close(); |
68 | } catch (IOException e) { |
69 | e.printStackTrace(); |
70 | } |
71 | } |
72 | for ( int i = 0 ; i < ids.size(); i++) { |
73 | Album album = new Album(ids.get(i), names.get(i), totals.get(i)); |
74 | result.add(album); |
75 | } |
76 | return result; |
77 | } |
4.下载一个相册。
1.得到一个相册的整个图片。
01 | /** |
02 | * 下载一个相册的图片 |
03 | * |
04 | * @param index 相册序号 |
05 | */ |
06 | public void savePhoto( final int index, final String qq) { |
07 | Album album = albums.get(index); |
08 | if (album.getName().indexOf( "微博" )>= 0 ){ |
09 | System.out.println( "微博相册不下载" ); |
10 | return ; |
11 | } |
12 | List<Photo> photosTemp = this .getPhotoByAlbum(album, qq, photobase1); |
13 | if (photosTemp == null || photosTemp.size() == 0 ) { |
14 | photosTemp = this .getPhotoByAlbum(album, qq, photobase2); |
15 | } |
16 | if (photosTemp == null || photosTemp.size() == 0 ) { |
17 | System.out.println( "相册信息为空" ); |
18 | return ; |
19 | } else { |
20 | final List<Photo> photos = photosTemp; |
21 |
22 |
23 | final int maxThreadCnt = 10 ; // 每个相册最多开启10个线程进行下载 |
24 | final int total = album.getCnt(); |
25 | int realThreadCnt = total >= maxThreadCnt ? maxThreadCnt : total; // 实际下载一个相册的线程数 |
26 | /** |
27 | * 线程驱动下载任务 |
28 | * |
29 | * <a href="http://my.oschina.net/arthor" target="_blank" rel="nofollow">@author</a> wensefu.jerry.Ling<br/> |
30 | * wrote on 2011-1-29 |
31 | */ |
32 | class DownLoadTask implements Runnable { |
33 | int id; // 线程标识 |
34 | int pindex; // 下载的图片指针 |
35 |
36 | public DownLoadTask( int id, int pindex) { |
37 | this .id = id; |
38 | this .pindex = pindex; |
39 | } |
40 |
41 | public void run() { |
42 | while (curIndex <= total - 1 ) { |
43 | int temp = pindex; |
44 | pindex = curIndex; |
45 | curIndex++; |
46 | Photo photo = photos.get(temp); |
47 | System.out.println( "线程" + (index + 1 ) + "_" + id + "开始下载第" + (index + 1 ) + "个相册第" + (pindex + 1 ) + "张图片..." ); |
48 | saveImgFromUrl(photo, qq); |
49 | System.out.println( "线程" + (index + 1 ) + "_" + id + "完成第" + (index + 1 ) + "个相册第" + (pindex + 1 ) + "张图片下载" ); |
50 | } |
51 | } |
52 | } |
53 | ExecutorService exec = Executors.newCachedThreadPool(); |
54 | /* |
55 | * 初始化各线程状态 此处给每个线程分配一个下载起始点 |
56 | */ |
57 | for ( int i = 0 ; i < realThreadCnt; i++) { |
58 | DownLoadTask task = new DownLoadTask(i + 1 , i); |
59 | exec.execute(task); |
60 | } |
61 | exec.shutdown(); |
62 | } |
63 | } |
1 |
1 |
1 |
1 | 源代码下载: http://www.oschina.net/code/snippet_557580_12818 |