經過抓包獲取QQ空間相冊的真實地址,實現空間相冊下載。

在網上找過相關的資料,都不是太全~有些缺漏。全部本身根據網上的再結合本身的修改了下。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
相關文章
相關標籤/搜索