news 2026/2/7 9:13:16

Java 爬虫对百科词条分类信息的抓取与处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 爬虫对百科词条分类信息的抓取与处理

在信息爆炸的互联网时代,百科类平台(如维基百科、百度百科)沉淀了海量结构化的知识内容,其词条的分类体系更是梳理信息的核心脉络。利用 Java 技术构建爬虫抓取并处理百科词条的分类信息,不仅能为知识图谱构建、行业数据分析、智能推荐系统等场景提供基础数据支撑,还能实现对特定领域知识的规模化采集与整合。本文将从技术原理、实现步骤、数据处理等维度,详细讲解如何使用 Java 完成百科词条分类信息的抓取与处理。

一、技术选型与核心原理

1. 核心技术栈

Java 生态中,爬虫开发的技术工具已十分成熟,本次实践选用以下核心技术:

  • 网络请求:Jsoup,一款轻量级的 HTML 解析库,支持 CSS 选择器、XPath 语法,能便捷地从 HTML 文档中提取数据,相比传统的 HttpClient + 正则表达式,开发效率更高。
  • 数据存储:MySQL,用于持久化存储抓取到的词条名称、分类路径、词条链接等结构化数据。
  • 数据处理:Java 集合框架(List、Map)与字符串处理工具(Apache Commons Lang3),用于清洗和规整分类信息。

2. 爬虫核心原理

百科词条的分类信息通常以固定的 HTML 结构呈现(如百度百科的分类栏位于页面侧边或底部,带有明确的 class 或 id 属性)。Java 爬虫的核心逻辑是:

  1. 发送 HTTP 请求获取词条页面的 HTML 源码;
  2. 解析 HTML 源码,定位分类信息的 DOM 节点,提取分类名称与链接;
  3. 对提取的原始数据进行清洗、去重、结构化处理;
  4. 将处理后的数据存储到数据库或本地文件中。

二、爬虫实现步骤:以百度百科为例

1. 环境准备

首先在 Maven 项目中引入依赖,核心依赖包括 Jsoup、MySQL 驱动、Apache Commons Lang3:

xml

<dependencies><!-- Jsoup HTML解析库 --><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.17.2</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version><scope>runtime</scope></dependency><!-- Apache Commons Lang3 工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.14.0</version></dependency></dependencies>

2. 发送 HTTP 请求获取 HTML 源码

使用 Jsoup 的<font style="color:rgba(0, 0, 0, 0.85) !important;">connect()</font>方法发送 GET 请求,设置请求头模拟浏览器访问(避免被反爬机制拦截),获取目标词条页面的 Document 对象(对应 HTML 文档)。

java

运行

importorg.jsoup.Jsoup;importorg.jsoup.nodes.Document;importjava.io.IOException;importjava.util.Map;/** * 网络请求工具类,用于获取百科页面的HTML源码 */publicclassHttpUtil{// 模拟浏览器的请求头privatestaticfinalMap<String,String>HEADERS=Map.of("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36","Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Accept-Language","zh-CN,zh;q=0.9,en;q=0.8");/** * 获取指定URL的Document对象 * @param url 目标URL * @return Document对象 * @throws IOException 网络请求异常 */publicstaticDocumentgetDocument(Stringurl)throwsIOException{Jsoup.Connectionconnection=Jsoup.connect(url);// 设置请求头for(Map.Entry<String,String>entry:HEADERS.entrySet()){connection.header(entry.getKey(),entry.getValue());}// 设置超时时间为10秒returnconnection.timeout(10000).get();}}

3. 解析 HTML 提取分类信息

百度百科的词条分类信息通常位于<font style="color:rgba(0, 0, 0, 0.85) !important;"><div class="basic-info cmn-clearfix"></font><font style="color:rgba(0, 0, 0, 0.85) !important;"><div class="category-wrap"></font>节点下,通过 Jsoup 的 CSS 选择器定位节点,提取分类名称和对应的链接。

java

运行

importorg.jsoup.nodes.Document;importorg.jsoup.nodes.Element;importorg.jsoup.select.Elements;importjava.util.ArrayList;importjava.util.List;/** * 百科页面解析工具类,用于提取分类信息 */publicclassBaikeParser{/** * 提取百度百科词条的分类信息 * @param doc 词条页面的Document对象 * @param entryName 词条名称 * @return 分类信息列表 */publicstaticList<Category>parseCategory(Documentdoc,StringentryName){List<Category>categoryList=newArrayList<>();// 方式1:定位分类栏节点(不同百科版本可能结构不同,可调整选择器)ElementscategoryElements=doc.select("div.category-wrap a[href]");if(categoryElements.isEmpty()){// 方式2:备用选择器,适配其他结构categoryElements=doc.select("ul.basic-info-list li a[href]");}// 遍历节点提取分类信息for(Elementelement:categoryElements){// 提取分类名称StringcategoryName=element.text().trim();// 提取分类链接(拼接完整URL)StringcategoryUrl="https://baike.baidu.com"+element.attr("href").trim();// 过滤空值if(!categoryName.isEmpty()&&!categoryUrl.isEmpty()){Categorycategory=newCategory();category.setEntryName(entryName);category.setCategoryName(categoryName);category.setCategoryUrl(categoryUrl);categoryList.add(category);}}returncategoryList;}}/** * 分类信息实体类 */classCategory{privateStringentryName;// 词条名称privateStringcategoryName;// 分类名称privateStringcategoryUrl;// 分类链接// 无参构造、有参构造、getter和setter方法publicCategory(){}publicCategory(StringentryName,StringcategoryName,StringcategoryUrl){this.entryName=entryName;this.categoryName=categoryName;this.categoryUrl=categoryUrl;}publicStringgetEntryName(){returnentryName;}publicvoidsetEntryName(StringentryName){this.entryName=entryName;}publicStringgetCategoryName(){returncategoryName;}publicvoidsetCategoryName(StringcategoryName){this.categoryName=categoryName;}publicStringgetCategoryUrl(){returncategoryUrl;}publicvoidsetCategoryUrl(StringcategoryUrl){this.categoryUrl=categoryUrl;}}

4. 数据清洗与存储

提取的原始分类信息可能存在重复、空值或无效字符,使用 Apache Commons Lang3 进行数据清洗,再将处理后的数据存入 MySQL 数据库。

java

运行

importorg.apache.commons.lang3.StringUtils;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.SQLException;importjava.util.List;/** * 数据处理与存储工具类 */publicclassDataProcessor{// MySQL数据库连接信息(需替换为自己的配置)privatestaticfinalStringDB_URL="jdbc:mysql://localhost:3306/baike_spider?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";privatestaticfinalStringDB_USER="root";privatestaticfinalStringDB_PASSWORD="123456";/** * 清洗分类信息(去重、去除空值和特殊字符) * @param categoryList 原始分类信息列表 * @return 清洗后的分类信息列表 */publicstaticList<Category>cleanCategory(List<Category>categoryList){returncategoryList.stream()// 过滤空值.filter(category->StringUtils.isNoneBlank(category.getEntryName(),category.getCategoryName(),category.getCategoryUrl()))// 去除特殊字符(保留中文、英文、数字).peek(category->{category.setCategoryName(StringUtils.replacePattern(category.getCategoryName(),"[^\\u4e00-\\u9fa5a-zA-Z0-9]",""));category.setEntryName(StringUtils.replacePattern(category.getEntryName(),"[^\\u4e00-\\u9fa5a-zA-Z0-9]",""));})// 去重(根据词条名称和分类名称).distinct().toList();}/** * 将分类信息存入MySQL数据库 * @param categoryList 清洗后的分类信息列表 * @throws SQLException 数据库操作异常 */publicstaticvoidsaveToMySQL(List<Category>categoryList)throwsSQLException{// 注册驱动(MySQL 8.0+可省略)try{Class.forName("com.mysql.cj.jdbc.Driver");}catch(ClassNotFoundExceptione){thrownewRuntimeException("加载MySQL驱动失败",e);}// SQL插入语句Stringsql="INSERT INTO baike_category (entry_name, category_name, category_url) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE category_url = VALUES(category_url)";try(Connectionconn=DriverManager.getConnection(DB_URL,DB_USER,DB_PASSWORD);PreparedStatementpstmt=conn.prepareStatement(sql)){// 批量插入数据for(Categorycategory:categoryList){pstmt.setString(1,category.getEntryName());pstmt.setString(2,category.getCategoryName());pstmt.setString(3,category.getCategoryUrl());pstmt.addBatch();}pstmt.executeBatch();System.out.println("数据存入数据库成功,共插入/更新"+categoryList.size()+"条记录");}}}

5. 主程序入口

整合上述工具类,实现从请求、解析、清洗到存储的完整流程:

java

运行

importorg.jsoup.nodes.Document;importjava.io.IOException;importjava.sql.SQLException;importjava.util.List;/** * 百科爬虫主程序 */publicclassBaikeSpiderMain{publicstaticvoidmain(String[]args){// 目标词条URL(以“Java语言”为例)StringentryUrl="https://baike.baidu.com/item/Java%E8%AF%AD%E8%A8%80";// 词条名称StringentryName="Java语言";try{// 1. 获取页面Document对象Documentdoc=HttpUtil.getDocument(entryUrl);// 2. 解析分类信息List<Category>rawCategoryList=BaikeParser.parseCategory(doc,entryName);// 3. 清洗分类信息List<Category>cleanCategoryList=DataProcessor.cleanCategory(rawCategoryList);// 4. 存入数据库DataProcessor.saveToMySQL(cleanCategoryList);}catch(IOExceptione){System.err.println("网络请求失败:"+e.getMessage());}catch(SQLExceptione){System.err.println("数据库操作失败:"+e.getMessage());}}}

三、反爬机制应对与优化建议

1. 反爬应对策略

百科平台通常设有反爬机制,实际开发中需注意:

  • 请求频率控制:添加延迟(如<font style="color:rgb(0, 0, 0);">Thread.sleep(1000)</font>),避免短时间内大量请求;
  • IP 代理池:若需大规模抓取,使用代理 IP 轮换,防止 IP 被封禁;推荐使用亿牛云隧道代理
  • Cookie 与 Session 维持:部分平台需要登录后访问,可通过 Jsoup 维持 Cookie 会话。

2. 性能优化

  • 多线程抓取:使用线程池(<font style="color:rgb(0, 0, 0);">ExecutorService</font>)并行处理多个词条,提升抓取效率;
  • 数据缓存:将频繁访问的分类信息缓存到 Redis 中,减少数据库查询压力;
  • 增量抓取:记录已抓取的词条 URL,只抓取新增词条,避免重复工作。

四、总结

本文通过 Jsoup、MySQL 等技术,实现了 Java 爬虫对百度百科词条分类信息的抓取、解析、清洗与存储。整个流程体现了 Java 爬虫开发的核心思路:从网络请求获取数据,到解析提取有效信息,再到数据的结构化处理与持久化。在实际应用中,可根据不同百科平台的页面结构调整解析规则,结合反爬策略与性能优化手段,实现规模化的知识信息采集。这种技术方案不仅适用于百科词条分类信息处理,还可拓展到电商商品分类、新闻资讯标签提取等场景,具有广泛的应用价值。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/5 4:15:14

低代码平台怎么选?这5款免费方案很友好

概述这两年不管是做业务系统、内部工具&#xff0c;还是想推进企业数字化&#xff0c;低代码平台真的帮了大忙。实际用下来会发现&#xff0c;选对平台&#xff0c;很多原本要排期开发的事情&#xff0c;用配置就能解决&#xff0c;而且成本压力也小很多。这里结合自己和身边朋…

作者头像 李华
网站建设 2026/2/7 6:48:15

HTML DOM 元素

HTML DOM 元素 HTML DOM(文档对象模型)是现代网页设计的基础。DOM 将 HTML 文档解析为一个树状结构,使得开发者能够通过编程方式操作网页内容、样式和行为。本文将深入探讨 HTML DOM 元素的概念、结构和用途。 概念 DOM(Document Object Model)是一种跨平台和语言独立的…

作者头像 李华
网站建设 2026/2/5 15:49:17

基于springboot+vue的微信小程序的公开课管理系统(源码+lw+部署文档+讲解等)

课题介绍随着在线教育的蓬勃发展&#xff0c;公开课因优质教育资源共享的特性备受青睐&#xff0c;但传统公开课管理模式存在课程信息分散、报名流程繁琐、学习进度难追踪、师生互动不便捷等痛点&#xff0c;影响教学效果与管理效率。本课题聚焦公开课教学管理场景&#xff0c;…

作者头像 李华
网站建设 2026/2/3 18:55:50

【配送路径规划】基于雪橇犬算法SDO求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿真…

作者头像 李华
网站建设 2026/2/3 5:57:52

挑企业微信 SCRM 迷茫?从私域转化需求切入,微伴助手凭什么是第一选择

现在用企业微信的老板越来越多&#xff0c;但不少人觉得 “不好用”—— 加客户慢、发消息没效果、员工离职带跑客户&#xff0c;问题一堆。其实不是企业微信本身不行&#xff0c;而是缺了合适的 “企业微信工具” 来补位。这些工具就像 “外挂”&#xff0c;能把企业微信的基础…

作者头像 李华