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

Java 爬虫实战:基于 HttpClient 爬取知乎百万用户数据

     編輯:Java 相關知識

知乎用户数据爬取系统设计与实现

本文分享一个基于 Java HttpClient 4.5 的知乎爬虫实战案例,实现了 90 万+ 活跃用户基础信息的自动化采集,涵盖模拟登录、多线程架构、去重策略等核心技术点。

系统整体架构

采用「生产者-消费者」双线程池模型:

  • 页面抓取线程池:负责发送 HTTP 请求,获取网页 HTML 内容,存入共享存储队列
  • 页面解析线程池:从队列取出 HTML,解析用户信息入库,提取关注列表 URL 重新放入抓取队列
  • 存储模块:线程安全的队列缓冲 HTML 内容,解耦抓取与解析

关键技术实现

1. 模拟登录与 Cookie 持久化

public boolean login(CloseableHttpClient client, HttpClientContext context) {
    // 1. 获取登录页 _xsrf token
    HttpGet get = new HttpGet("https://www.zhihu.com/#signin");
    HttpClientUtil.getWebPage(client, context, get, "utf-8", false);
    
    // 2. 处理验证码(人工识别)
    String captcha = downloadAndRecognizeCaptcha(client, context);
    
    // 3. 提交登录表单
    HttpPost post = new HttpPost("https://www.zhihu.com/login/email");
    List<NameValuePair> params = new ArrayList<>();
    params.add(new BasicNameValuePair("captcha", captcha));
    params.add(new BasicNameValuePair("email", "你的邮箱"));
    params.add(new BasicNameValuePair("password", "你的密码"));
    params.add(new BasicNameValuePair("remember_me", "true"));
    post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
    
    String result = HttpClientUtil.getWebPage(client, context, post, "utf-8", false);
    JSONObject json = new JSONObject(result);
    if ("0".equals(json.getString("r"))) {
        // 登录成功,序列化 Cookie 到磁盘
        HttpClientUtil.serializeObject(context.getCookieStore(), "zhihu_cookies");
        return true;
    }
    return false;
}

2. URL 去重策略

使用 MD5 哈希处理 URL 后存入数据库,每次抓取前查询是否存在:

String urlMd5 = DigestUtils.md5Hex(url);
if (db.exists(urlMd5)) return; // 已抓取
db.save(urlMd5); // 标记为已抓取

3. 核心爬取循环

// 解析线程逻辑
while (running) {
    String html = storage.take(); // 从队列获取 HTML
    User user = parseUserProfile(html); // 解析用户信息
    userDao.save(user); // 入库
    
    List<String> followUrls = parseFollowUrls(html); // 提取关注列表
    for (String url : followUrls) {
        if (!db.exists(DigestUtils.md5Hex(url))) {
            fetchPool.submit(() -> fetchPage(url)); // 提交给抓取线程池
        }
    }
}

运行成果与注意事项

  • 成功抓取 100 万+ 用户,访问链接 220 万+
  • 后期多为低活跃用户,高活跃用户基本覆盖完毕
  • 合规提醒:爬虫需遵守 robots.txt,控制频率,仅供技术研究,切勿用于商业用途

项目地址

GitHub: https://github.com/wycm/mycrawler

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