首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

QQ 聯系人導入方案(上):模擬瀏覽器登錄 QQ 郵箱獲取聯系人

     編輯:關於JSP

背景與挑戰

項目需導入 QQ 聯系人,但騰訊未開放官方 API。開源協議庫 LumaQQ 登錄不穩定,維護成本高。發現 QQ 郵箱(mail.qq.com) 可在瀏覽器查看聯系人,決定採用「程序模擬瀏覽器登錄郵箱 → 解析聯系人頁面」方案。

技術路線

  1. 分析 QQ 郵箱登錄 HTTP 請求/響應流程(抓包工具:Fiddler/Charles/Wireshark)。
  2. 提取關鍵參數:uin(QQ號)、p(加密密碼)、verifycode(驗證碼)、sid、ts 等。
  3. 實現 RSA 加密密碼(JS 加密邏輯移植至 Java)。
  4. 模擬提交登錄表單,獲取並維護 Cookie(sid、qqmail_sid 等)。
  5. 訪問聯系人列表頁面,解析 HTML/JSON 獲取聯系人數據。

登錄請求分析 (HTTP/1.1)

POST /cgi-bin/login?sid=0,2,zh_CN HTTP/1.1
Host: m126.mail.qq.com
User-Agent: Mozilla/5.0 ...
Content-Type: application/x-www-form-urlencoded
Cookie: verifysession=...; pvid=...; r_cookie=...

sid=0%2C2%2Czh_CN&firstlogin=false&starttime=1251436516205
&f=html&p=UyoLX7JYspcnU9wCUK7qBA2Xjwo%2FO52FldnJnRABCnNLXI1ndwR8%2BQaepkT%2FIcKHxMshWv4SjrxgvRtA%2B1eHAookTXzcia%2FhP5QrRlGyNoqzVCi1X%2FsJwb4SmjPZRwV%2B7WeskUwClUfeNv%2BmCq0ygoNzi9UnIVeI7lYzgqXnxZE%3D
&delegate_url=&s=&ts=1251436494&uin=XXXXXXXX&aliastype=%40qq.com&pp=000000000&verifycode=qmpb

關鍵字段說明:

  • p:RSA 加密後的密碼,格式為 密碼\nTS\n 經公鑰加密再 Base64。
  • ts:時間戳,從登錄頁面獲取。
  • verifycode:驗證碼輸入值。
  • uin:QQ 號。

登錄響應關鍵 Cookie

Set-Cookie: sid=6449e26f4adc402ac5c80e08bec3ca6c; Domain=mail.qq.com; Path=/
Set-Cookie: username=XXXXXXXX; Domain=mail.qq.com; Path=/
Set-Cookie: qqmail_sid=6449e26f4adc402ac5c80e08bec3ca6c; Domain=qq.com; Path=/
Set-Cookie: qqmail_key=1_de7d3652ab10a1616175bf2aab152fb7010b0d06020602060309; Domain=qq.com; Path=/

後續請求必須攜帶上述 Cookie(特別是 sid、qqmail_sid、qqmail_key)。

核心難點與解決方案

難點解決方案
密碼 RSA 加密從登錄頁面 JS (auth.js) 提取公鑰模數/指數,Java 端用 RSAPublicKeySpec 重現加密邏輯,或直接調用 JS 引擎 (Rhino/Nashorn) 執行原 JS 代碼。
驗證碼識別人工輸入 / 打碼平台 / 簡單圖片識別 (Tesseract) / 避開需驗證碼的登錄入口(如二維碼登錄)。
動態參數 (ts, starttime)每次登錄前先 GET 登錄頁面解析隱藏字段,實時構造表單。
Cookie 管理使用 HttpClient (Apache HttpComponents) 自動維護 CookieStore,支持重定向。
反爬蟲風控控制請求頻率、模擬真實 User-Agent、使用代理 IP 池、處理滑塊/設備指紋驗證。

Java 端核心代碼骨架

public class QQMailContactImporter {
    private CloseableHttpClient httpClient;
    private String qq, pwd;

    public QQMailContactImporter(String qq, String pwd) {
        this.qq = qq; this.pwd = pwd;
        this.httpClient = HttpClients.custom()
            .setDefaultCookieStore(new BasicCookieStore())
            .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...")
            .build();
    }

    public List importContacts() throws Exception {
        // 1. 獲取登錄頁面,解析公鑰、ts、verifycode URL
        LoginPageInfo info = fetchLoginPage();
        // 2. 獲取驗證碼圖片(可選)
        // 3. RSA 加密密碼
        String encryptedPwd = RSAEncrypt.encrypt(pwd + "\n" + info.ts + "\n", info.publicKey);
        // 4. 提交登錄表單
        boolean loginOk = submitLogin(info, encryptedPwd, "verifycode_input");
        if (!loginOk) throw new RuntimeException("登錄失敗");
        // 5. 訪問聯系人列表頁面
        String contactsHtml = fetchContactsPage();
        // 6. 解析聯系人數據
        return parseContacts(contactsHtml);
    }
    // ... 省略具體方法實現
}

法律與道德提示

  • 僅供技術研究,嚴禁用於大規模爬取、垃圾營銷、隱私侵犯。
  • 騰訊服務協議禁止未授權自動化訪問,生產環境請申請官方開放平台權限(如 QQ 互聯)。
  • 用戶密碼屬極高敏感信息,嚴禁明文存儲/日誌記錄,建議採用 OAuth 授權碼模式替代密碼模式。

下篇預告

下篇將詳細講解:RSA 加密 Java 實現、聯系人列表頁面解析策略、完整可運行 Demo 代碼、異常處理與重試機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved