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

WebHarvest網絡爬蟲實戰:基於XML配置的天涯論壇版塊抓取

     編輯:Java 相關知識

WebHarvest是基於XML配置的Java開源爬蟲框架,通過HttpClient獲取頁面,結合XPath/XQuery/正則提取結構化數據。本文以抓取天涯論壇版塊結構為例,詳細講解配置文件編寫與Java集成。

目標頁面分析

天涯版塊地圖:https://www.tianya.cn/bbs/index.shtml


<div class="backrgoundcolor">
  <div class="bankuai_list">
    <h3>社會民生</h3>
    <ul>
      <li><a href="..." id="item天涯雜談">天涯雜談</a></li>
      <li><a href="..." id="item國際觀察">國際觀察</a></li>
      ...
    </ul>
  </div>
</div>
<div class="nobackrgoundcolor">
  <div class="bankuai_list">
    <h3>文學讀書</h3>
    <ul>...</ul>
  </div>
</div>

規律:每個大版塊在<div class="bankuai_list">中,包含<h3>標題和<ul><li><a>子版塊列表。

WebHarvest配置文件 (tianya.xml)


<?xml version="1.0" encoding="UTF-8"?>
<config charset="utf-8">
  <!-- 1. 定義入口變量 -->
  <var-def name="startPage">
    <html-to-xml>
      <http url="https://www.tianya.cn/bbs/index.shtml" charset="utf-8" />
    </html-to-xml>
  </var-def>

  <!-- 2. 提取所有版塊列表容器 -->
  <var-def name="categoryNodes">
    <xpath expression="//div[@class='bankuai_list']">
      <var name="startPage" />
    </xpath>
  </var-def>

  <!-- 3. 遍歷生成XML輸出 -->
  <file action="write" path="tianya/siteboards.xml" charset="utf-8">
    <![CDATA[ <site> ]]>
    <loop item="catNode" index="i">
      <list><var name="categoryNodes"/></list>
      <body>
        <xquery>
          <xq-param name="catNode"><var name="catNode"/></xq-param>
          <xq-expression><![CDATA[
            declare variable $catNode as node() external;
            <category name="{normalize-space($catNode//h3/text())}">
            {
              for $item in $catNode//li return
                <board name="{normalize-space($item//a/text())}" 
                       url="{normalize-space($item/a/@href)}" />
            }
            </category>
          ]]></xq-expression>
        </xquery>
      </body>
    </loop>
    <![CDATA[ </site> ]]>
  </file>
</config>

配置關鍵點解析

元素作用關鍵屬性
<var-def>定義變量name: 變量名
<http>發送HTTP請求url, charset, method, headers
<html-to-xml>HTML轉標準XML容錯解析
<xpath>XPath提取節點expression: XPath表達式
<xquery>XQuery轉換輸出支持循環/條件/構造XML
<loop>遍歷集合item: 迭代變量名, list: 數據源
<file>寫入文件path, action(write/append), charset

Java集成代碼


public class TianyaCrawler {
    public static void main(String[] args) {
        String configFile = "tianya.xml";
        String targetDir = "c:/crawler_output";
        
        try {
            // 1. 載入配置
            ScraperConfiguration config = new ScraperConfiguration(configFile);
            
            // 2. 創建爬蟲實例
            Scraper scraper = new Scraper(config, targetDir);
            
            // 3. 設置代理(可選)
            scraper.getHttpClientManager().setHttpProxy("proxy.example.com", 8080);
            
            // 4. 啟用調試
            scraper.setDebug(true);
            
            // 5. 動態注入變量(如分頁參數)
            // scraper.addVariableToContext("pageNum", 1);
            
            // 6. 執行爬取
            scraper.execute();
            
            System.out.println("爬取完成,輸出: " + targetDir + "/tianya/siteboards.xml");
            
        } catch (Exception e) {
            System.err.println("爬取失敗: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

動態配置進階:分頁抓取


<config>
  <var-def name="pageNum">1</var-def>
  
  <loop item="page" index="p">
    <list><var name="pageNum"/></list> <!-- 這裡需配合script生成頁碼列表 -->
    <body>
      <var-def name="pageUrl">
        <script><![CDATA[
          "https://example.com/list?page=" + page
        ]]></script>
      </var-def>
      
      <var-def name="pageDoc">
        <html-to-xml>
          <http url="${pageUrl}" charset="utf-8"/>
        </html-to-xml>
      </var-def>
      
      <!-- 提取數據 -->
      <xpath expression="//div[@class='item']">
        <var name="pageDoc"/>
      </xpath>
    </body>
  </loop>
</config>

輸出結果示例 (siteboards.xml)


<site>
  <category name="社會民生">
    <board name="天涯雜談" url="https://www.tianya.cn/publicforum/articleslist/0/free.shtml"/>
    <board name="國際觀察" url="https://www.tianya.cn/publicforum/articleslist/0/worldlook.shtml"/>
    <board name="天涯時空" url="https://www.tianya.cn/publicforum/articleslist/0/news.shtml"/>
  </category>
  <category name="文學讀書">
    <board name="蓮蓬鬼話" url="https://www.tianya.cn/techforum/articleslist/0/16.shtml"/>
    <board name="煮酒論史" url="https://www.tianya.cn/publicforum/articleslist/0/no05.shtml"/>
  </category>
  ...
</site>

反爬蟲應對與最佳實踐

  • 請求頻控:Thread.sleep(random(1000,3000))或配置<delay>
  • User-Agent輪換:<http header="User-Agent" value="${uaList[random()]}"/>
  • Cookie管理:HttpClientManager.setCookieStore()持久化會話
  • 異常重試:捕獲HttpException指數退避重試3次
  • 增量爬取:記錄Last-Modified/ETag,配合If-Modified-Since

現代替代方案對比

WebHarvest以「配置驅動」特性適合快速原型與非程序員維護,但現代項目建議使用Jsoup/WebMagic獲得更好的類型安全、IDE支持與生態兼容性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
框架配置方式Java版本維護狀態適用場景
WebHarvestXML1.5+停止更新簡單靜態頁、遺留項目
Jsoup代碼API1.8+活躍HTML解析、輕量爬取
WebMagic代碼/註解1.8+活躍分佈式爬蟲、結構化項目
Crawler4j代碼1.8+活躍大規模遞歸爬取