Как мы показываем чистые выдержки в стиле Google в наших результатах поиска?
Мы используем dtSearch для индексации некоторых внешних веб-страниц. Он захватывает весь HTML-контент страницы.
Когда страница отображается в списке результатов поиска на нашем веб-сайте, мы хотим показать отрывок контента, который содержит выделенный / выделенный поисковым термином, как часть результата (другими словами, то же самое, что используется всеми видя под каждым гуглом результат).
Какой это лучший способ сделать это? Нужно ли анализировать и удалять теги HTML? Если да, то как вы делаете это эффективно?
У нас есть доказательство работоспособности концепции, показывающая выдержку с выделенными поисковыми терминами, но мы должны либо визуализировать теги, либо попытаться удалить их (как мы уже пытались) и получить некоторую информацию о мусоре, которая на самом деле не является контентом.
Я думаю, что тот факт, что мы используем dtSearch, является случайным. Если альтернативный поисковый инструмент способен сделать что-то подобное от нашего имени, мы бы решили использовать его вместо этого.
Мы в основном пытаемся решить, нужно ли нам создавать собственные регулярные выражения для достижения этой цели или это известная проблема, которая уже решена какой-то библиотекой или инструментом.
Мы используем.NET/C#. Я не думаю, что это является центральной проблемой, но может повлиять на то, какие библиотеки мы можем использовать.
3 ответа
Google использует meta
теги описания, если они присутствуют, а также будут использовать расширенную информацию о фрагментах, где это возможно.
Кроме того, вам может потребоваться выполнить пользовательский анализ, но не используйте регулярные выражения для выполнения всей задачи. Вместо этого используйте правильный синтаксический анализатор (такой как HTML Aglity Pack) и найдите теги, которые имеют смысловой смысл (возможно, заголовки, абзацы и т. Д.). После того, как вы нашли такие элементы, вы можете использовать регулярное выражение, чтобы определить, какой из совпавших тегов даст Вы лучший фрагмент, где его урезать и т. д.
Простой поток:
- проанализируйте документ и найдите все элементы со значительным объемом текстового содержимого.
- убрать внутренние метки (например,
strong
внутриp
) - предпочитаю элементы в начале документа.
- запустить алгоритм (возможно, с помощью регулярных выражений (и), и, возможно, с учетом культуры), чтобы попытаться извлечь предложения.
- Настоятельно предпочитайте предложения со словами, соответствующими одному или нескольким условиям поиска (в зависимости от заявленных вами требований)
- предпочитаю предложения с несколькими шумовыми словами.
- (продвинутый) предпочитают предложения, слова которых встречаются в документе регулярно.
- (продвинутый) объединить несколько потенциально полезных предложений в один фрагмент описания.
Это не точная наука, даже для Google.
Вот что я использую для генерации сводки поиска для элемента с помощью 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, которое может быть установлено для объекта, который имеет набор методов, которые вызываются в ходе поиска. Используя это, вы можете обрабатывать файлы в том виде, в котором они были найдены, и поддерживать отзывчивость интерфейса, не перегружая поток интерфейса. как: SJob1.StatusHandler = это; SJob1.Execute ();
SJob1.StatusHandler = this; SJob1.ExecuteInThread (); Вызов StatusHandler OnFound встречался каждый раз, когда документ был найден, поэтому, если документ не найден, метод OnFound не выполняется, поэтому больше не загружается.