如何在Nutch爬取流程中拆分段落并导入Solr,添加位置与章节字段?
我来帮你搞定这个需求——要在Nutch爬取流程里实现段落拆分并带上位置和章节信息,核心是扩展Nutch的解析插件,把单文档拆成多个段落级的子文档再推给Solr。下面是一步步的具体实现方法:
1. 编写自定义解析过滤器插件
Nutch的解析阶段是通过插件扩展的,我们需要写一个ParseFilter实现类,来完成段落拆分、章节提取和元数据添加。
1.1 搭建插件目录结构
在Nutch源码的src/plugin下新建parse-paragraph目录,结构如下:
parse-paragraph/ ├── build.xml ├── plugin.xml └── src/ └── main/ └── java/ └── com/ └── yourdomain/ └── nutch/ └── parse/ └── ParagraphParseFilter.java
1.2 实现ParseFilter类
用Java编写核心逻辑,这里用Jsoup来解析HTML(方便提取h2和段落),示例代码如下:
import org.apache.hadoop.conf.Configuration; import org.apache.nutch.parse.*; import org.apache.nutch.metadata.Metadata; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.nio.charset.StandardCharsets; public class ParagraphParseFilter implements ParseFilter { private Configuration conf; @Override public void setConf(Configuration conf) { this.conf = conf; } @Override public Configuration getConf() { return conf; } @Override public ParseResult filter(Content content, ParseResult parseResult, ParseContext parseContext) { ParseResult paragraphResults = new ParseResult(); Parse originalParse = parseResult.get(content.getUrl()); String htmlContent = new String(content.getContent(), StandardCharsets.UTF_8); // 用Jsoup解析HTML文档 Document doc = Jsoup.parse(htmlContent); Elements allH2 = doc.select("h2"); Elements allParagraphs = doc.select("p"); int paragraphIndex = 1; String currentSection = "无章节"; // 默认章节名称 // 遍历所有段落,生成段落级解析结果 for (Element para : allParagraphs) { String paraText = para.text().trim(); if (paraText.isEmpty()) continue; // 更新当前段落所属的最近h2章节 for (Element h2 : allH2) { if (h2.isBefore(para) && (h2.nextElementSibling() == para || h2.nextElementSibling().isBefore(para))) { currentSection = h2.text().trim(); } } // 构建段落的元数据 Metadata paraMeta = new Metadata(); paraMeta.add("paragraph_position", String.valueOf(paragraphIndex)); paraMeta.add("paragraph_section", currentSection); // 保留原文档的关键信息,方便关联 paraMeta.add("original_url", content.getUrl()); paraMeta.add("original_title", originalParse.getTitle()); // 创建段落的Parse对象 ParseText paraTextObj = new ParseText(paraText); Parse paraParse = new ParseImpl(paraTextObj, paraMeta); // 用原URL+段落索引作为唯一标识,添加到结果集 String paraKey = content.getUrl() + "#para_" + paragraphIndex; paragraphResults.put(paraKey, paraParse); paragraphIndex++; } // 如果没有提取到段落,返回原解析结果(避免丢失数据) return paragraphResults.isEmpty() ? parseResult : paragraphResults; } }
1.3 配置插件文件
- plugin.xml:声明插件和依赖
<plugin id="parse-paragraph" name="Paragraph Parse Filter" version="1.0.0" provider-name="yourdomain.com"> <runtime> <library name="parse-paragraph.jar"/> <!-- 引入jsoup依赖,确保jar包在插件的lib目录下 --> <library name="jsoup-1.17.2.jar"/> </runtime> <requires> <import plugin="nutch-extensionpoints"/> <import plugin="parse-api"/> <import plugin="parse-html"/> </requires> <extension id="com.yourdomain.nutch.parse.ParagraphParseFilter" name="Paragraph Parse Filter" point="org.apache.nutch.parse.ParseFilter"> <implementation id="ParagraphParseFilter" class="com.yourdomain.nutch.parse.ParagraphParseFilter"/> </extension> </plugin>
- build.xml:配置编译规则(参考其他解析插件的build.xml,确保能正确编译打包)
1.4 编译插件
把jsoup的jar包放到parse-paragraph/lib目录,然后在Nutch根目录执行:
ant clean runtime
这会把自定义插件编译并打包到runtime/local目录的插件文件夹里。
2. 配置Nutch启用自定义插件
编辑conf/nutch-site.xml,修改plugin.includes属性,加入你的自定义插件:
<property> <name>plugin.includes</name> <value>... parse-paragraph ...</value> <!-- 确保parse-paragraph在parse-html之后加载 --> </property>
3. 调整Solr配置
3.1 修改Solr Schema
在Solr的nutch core的managed-schema(或schema.xml)里添加两个字段:
<field name="paragraph_position" type="int" indexed="true" stored="true"/> <field name="paragraph_section" type="text_general" indexed="true" stored="true"/> <field name="original_url" type="string" indexed="true" stored="true"/> <!-- 可选,关联原文档 -->
3.2 配置Nutch到Solr的字段映射
编辑conf/solr-mapping.xml,添加自定义字段的映射:
<field dest="paragraph_position" source="paragraph_position"/> <field dest="paragraph_section" source="paragraph_section"/> <field dest="original_url" source="original_url"/>
4. 修正爬取脚本的Solr URL
注意你的原脚本里Solr URL带了/#/,这是UI路径,API请求应该直接指向core,修改为:
bin/crawl -i -D solr.server.url=http://localhost:8983/solr/nutch -s ./urls/ Crawl 2
关键注意事项
- 测试时先小规模爬取单个站点,查看Solr索引里的段落数据是否正确,包括位置和章节信息。
- 如果文档中有嵌套的章节结构(比如h2下的h3),可以扩展逻辑调整章节提取规则。
- 性能方面,长文档拆分后会生成大量索引条目,需根据实际情况调整Solr的索引优化参数。
内容的提问来源于stack exchange,提问作者Alejandro
相关产品推荐
相关产品推荐

