我们如何在搜索结果中显示干净的 Google 风格的摘录
本文关键字:Google 风格 显示 搜索结果 我们 | 更新日期: 2023-09-27 17:57:23
我们使用dtSearch来索引一些外部网页。它抓取页面的整个HTML内容。
当一个页面出现在我们网站的搜索结果列表中时,我们希望显示包含其突出显示/粗体搜索词的内容摘录作为结果的一部分(换句话说,每个人都习惯于在每个 Google 结果下看到相同的内容)。
实现这一目标的最佳方法是什么?您是否必须解析和删除 HTML 标记?如果是这样,您如何有效地做到这一点?
我们有一个概念证明工作,显示突出显示搜索词的摘录,但我们必须呈现标签,或者尝试将它们删除(正如我们已经尝试过的那样),最终得到一些垃圾信息,这些信息并不是真正的内容。
我认为,我们使用dtSearch的事实是偶然的。如果替代搜索工具能够代表我们做这种事情,我们会考虑使用它。
我们基本上是在尝试决定是否需要编写自己的正则表达式来完成此操作,或者这是否是一个众所周知的问题,已经由某些库或工具解决了。
我们碰巧正在使用 .NET/C#。我不认为这是问题的核心,但可能会影响我们可以使用的库。
Google 会在存在的情况下使用meta
描述标签,并在可用的情况下使用丰富网页摘要信息。
除此之外,您可能需要执行自定义解析,但不要使用正则表达式来执行整个任务。相反,使用适当的解析器(例如HTML Aglity Pack)并查找语义有意义的标签(可能是标题,段落等)。找到这些元素后,您可以使用正则表达式来确定哪些匹配的标签将为您提供最佳代码段,在哪里截断它等。
一个简单的流程:
- 解析文档并找到大量元素的所有元素的文本内容。
- 剥离内部标签(例如
strong
p
内
) - 首选文档开头附近的元素。
- 运行算法(可能使用正则表达式,可能使用区域性感知)以尝试提取句子。
- 强烈喜欢单词与一个或多个搜索词匹配的句子(基于您声明的要求)。
- 更喜欢带有少量噪音词的句子。
- (高级)更喜欢文档中经常出现的单词的句子。
- (高级)将多个可能有用的句子组合成一个描述片段。
这不是一门精确的科学,即使对谷歌来说也是如此。
以下是我用来使用 dtsearch 生成项目的搜索摘要的方法(使用文档文本的缓存存储版本):
您的问题的关键点是rj.OutputFormat = dtSearch.Engine.OutputFormats.itUTF8;
(它覆盖默认的 html 格式)您应该获得带有粗体突出显示的清理摘要。
希望这会有所帮助
public string GetSumary(String ItemEncoded)
{
using (var res = new dtSearch.Engine.SearchResults())
{
res.UrlDecodeItem(ItemEncoded);
res.GetNthDoc(0);
using (var rj = res.NewSearchReportJob())
{
// next line asumes you store your document text version in cache. remove if not
rj.Flags |= dtSearch.Engine.ReportFlags.dtsReportGetFromCache;
rj.Flags |= dtSearch.Engine.ReportFlags.dtsReportByWordExact;
rj.Flags |= dtSearch.Engine.ReportFlags.dtsReportLimitContiguousContext;
rj.OutputToString = true;
rj.OutputFormat = dtSearch.Engine.OutputFormats.itUTF8;
rj.OutputStringMaxSize = 2000;
rj.MaxContextBlocks = 1;
rj.WordsOfContext = 12;
rj.Header = "";
rj.FileHeader = "";
rj.ContextHeader = "";
rj.BeforeHit = "<b>";
rj.AfterHit = "</b>";
rj.ContextFooter = "";
rj.ContextSeparator = " ... ";
rj.FileFooter = "";
rj.Footer = "";
rj.SelectItems(0, 0);
rj.Execute();
// some final clean-up
return
new Regex(@"['t'r'n]+|['.;','*]{2,}").Replace(rj.OutputString, " "); }
}
}
Use dtsearch ISearchStatusHandler interface with OnFound method, OnFound method Called each time a document is found
public class HomeController : Controller, ISearchStatusHandler
{
public void Search()
{
SearchJob sj = new SearchJob();
sj.Request = "fast";
sj.IndexesToSearch.Add(@"D:'R & D'Indexpath'aaa");
sj.SearchFlags = SearchFlags.dtsSearchSynonyms &
SearchFlags.dtsSearchWordNetRelated;
sj.Execute();
SearchResults result = sj.Results;
}
public void OnFound(SearchResultsItem item)
{
int DocId = item.DocId;
string FileName = item.Filename;
}
public void OnSearchingFile(string filename)
{
throw new NotImplementedException();
}
public void OnSearchingIndex(string index)
{
throw new NotImplementedException();
}
}
有一种更有条理和更全面的方式来处理获得搜索结果。SearchJob 对象具有一个 StatusHandler 属性,该属性可以设置为具有一组随搜索过程中调用的方法的对象。使用此功能,您可以在找到文件时处理文件,并且可以通过不占用 UI 线程来保持 UI 响应。比如:SJob1.StatusHandler = this;SJob1.Execute();
SJob1.StatusHandler = this;SJob1.ExecuteInThread();状态处理程序调用 OnFound 每次找到文档时都会调用 OnFound 方法,因此如果找不到文档,则 OnFound 方法不会执行,因此不再加载。