在网上找过相关的资料,都不是太全~有些缺漏。所有自己根据网上的再结合自己的修改了下。
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 |