專案目標拆解
| 階段 | 需求 | 技術難點 |
| 1 | 模擬瀏覽器訪問知乎首頁 | Cookie 管理、User-Agent 偽裝、重定向處理 |
| 2 | 抓取「今日熱榜」「本月熱榜」「編輯推薦」 | 頁面結構解析、動態渲染數據提取 |
| 3 | 按分類(投資/編程/掛科)全量抓取問答 | 分頁邏輯、增量去重、速率控制 |
| 4 | 指定答主全量回答導出 | 用戶主頁翻頁、答案內容清洗 |
| 5 | 一鍵批量點贊(異常功能) | 登錄態維護、簽名算法逆向、風控繞過 |
技術棧選型
- 語言:Java 17+(強類型、生態豐富、並發優秀)
- HTTP 客戶端:HttpClient 5 / OkHttp 4 — 支持連接池、攔截器、異步
- HTML 解析:Jsoup — 選擇器語法、容錯性強
- 動態渲染:Selenium / Playwright / Puppeteer-java — 處理 JS 渲染頁面
- 持久化:SQLite / MySQL + MyBatis — 增量爬取去重
- 調度:Spring Scheduler / Quartz — 定時任務、分佈式鎖
環境準備清單
- JDK 17 + Maven/Gradle
- IDE:IntelliJ IDEA Community(推薦)或 VS Code
- 瀏覽器:Chrome/Edge + 開發者工具(Network、Elements、Application 必會)
- 抓包工具:Fiddler / Charles / Proxyman — 分析 HTTPS 請求、攔截修改
核心模塊設計
1. 請求封裝層
@Component
public class ZhihuHttpClient {
private final CloseableHttpClient client;
private final CookieStore cookieStore = new BasicCookieStore();
public ZhihuHttpClient() {
this.client = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore)
.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
.build();
}
public String get(String url) throws IOException {
HttpGet get = new HttpGet(url);
get.setHeader("Referer", "https://www.zhihu.com/");
get.setHeader("X-Requested-With", "fetch");
return client.execute(get, response -> EntityUtils.toString(response.getEntity()));
}
}
2. 解析層
public class HotListParser {
public List parse(String html) {
Document doc = Jsoup.parse(html);
return doc.select("div.HotList-item").stream().map(el -> {
HotItem item = new HotItem();
item.setTitle(el.select(".HotItem-title").text());
item.setHot(el.select(".HotItem-metrics").text());
item.setLink("https://www.zhihu.com" + el.select("a").attr("href"));
return item;
}).collect(Collectors.toList());
}
}
3. 反爬對抗策略
| 風控手段 | 應對方案 |
| IP 限頻 | 代理池輪換、指數退避重試 |
| UA/指紋檢測 | 真實瀏覽器指紋庫、Playwright 無頭模式 |
| 登錄態失效 | Cookie 定時刷新、掃碼登錄自動化 |
| JS 加密簽名 | Node.js 執行簽名算法 / Java 移植 / RPC 調用簽名服務 |
| 驗證碼 | 打碼平台 / 人工介入 / 行為模擬降低觸發率 |
合規與倫理紅線
⚠️ 必讀:
- 遵守
robots.txt 與《知乎用戶協議》
- 控制爬取頻率(建議 > 2s/請求),不影響正常服務
- 僅抓取公開數據,不繞過登錄/權限獲取私有內容
- 數據僅供個人學習/研究,嚴禁商業化分發
- 「一鍵點贊」屬於模擬用戶行為操作,**極大概率違反平台規則,切勿實施**
項目結構建議
zhihu-crawler
├── src/main/java/com/example/crawler
│ ├── config // 代理、限流、選擇器配置
│ ├── client // HTTP 客戶端、Cookie 管理
│ ├── parser // Jsoup/JSON 解析器
│ ├── model // 實體類
│ ├── pipeline // 存儲、去重、導出
│ ├── scheduler // 任務調度、分佈式鎖
│ └── anti // 反爬對抗、簽名服務
└── resources
├── application.yml
└── selectors.yml // CSS/XPath 選擇器外置化
下一步行動
- 搭建 Spring Boot 專案,接入 HttpClient + Jsoup
- 用瀏覽器開發者工具分析「熱榜」接口(通常為
/api/v3/feed/topstory/hot-lists/total)
- 直接調用 JSON API 而非解析 HTML —— **效率提升 10 倍**
- 建立 SQLite 本地庫,設計
question/answer/author 三表
- 編寫定時任務,增量同步,配合去重鍵
question_id
工欲善其事,必先利其器。從「抓包分析接口」開始,比「解析 HTML」更穩健、更優雅。