2013-02-01 66 views
2

我們使用dtSearch來索引一些外部網頁。它抓取頁面的整個HTML內容。我們如何在搜索結果中顯示乾淨的Google樣式摘錄?

當一個頁面在我們的網站上的搜索結果列表中顯示,我們要顯示一個包含其高亮/加粗搜索詞作爲結果的一部分內容的摘錄(換句話說,每個人都習慣在每個Google結果下看到同樣的事情)。

完成此操作的最佳方法是什麼?你需要解析和刪除HTML標籤嗎?如果是這樣,你如何有效地做到這一點?

我們有一個概念驗證的工作,顯示突出顯示搜索條件的摘錄,但我們必須呈現標籤,或試圖剝離它們(正如我們試過的),並最終得到一些垃圾信息不是真的滿足。

我認爲我們使用dtSearch的事實是偶然的。如果替代搜索工具能夠代表我們完成這種類型的事情,我們會考慮使用它。

我們基本上試圖決定是否需要編寫我們自己的正則表達式來完成這個任務,或者它是一個已知問題已經被某個庫或工具解決了。

我們恰好​​使用.NET/C#。我認爲這不是問題的核心,但可能會影響我們可以使用的庫。

+0

使用Google?許多網站嵌入谷歌搜索... – vonbrand

+0

谷歌節目的摘錄取決於你搜索什麼..因此,可以有多個同一網站摘錄!以及爲什麼要刪除html標記!還使用'regex'來解析html是**不推薦... – Anirudha

+0

我應該補充說,除了索引外部網頁之外,我們還將索引我們自己的一些數據庫內容。至於使用Google搜索,我不確定搜索自己的數據庫而不是抓取頁面的能力,我也不確定您可以在多大程度上自定義結果的外觀。 –

回答

3

Google使用meta描述標籤哪裏出現,並且還將使用可用的rich snippet information

除此之外,您可能需要執行自定義分析,但不要使用正則表達式來執行整個任務。相反,使用合適的解析器(例如HTML Aglity Pack)並找到具有語義意義的標籤(可能是標題,段落等)。找到這些元素後,您可以使用正則表達式來確定哪些匹配的標籤可以爲您提供最好片段,其中截斷它等

一個簡單的流程圖:

  1. 解析文檔並找到所有元素與文本內容一個顯著量 。
  2. 帶內標籤(例如p內的strong
  3. 更喜歡靠近文檔開頭的元素。
  4. 運行算法(可能使用正則表達式,可能還有文化意識)嘗試提取語句。
  5. 強烈推薦使用符合一個或多個搜索詞的詞(根據您的要求)。
  6. 優先選擇帶有少量噪音的詞語。
  7. (高級)更喜歡在文檔中定期出現單詞的句子。
  8. (高級)將多個可能有用的句子組合成單個描述片段。

這不是一門精確的科學,即使是Google。

0

下面是我用它來生成搜索摘要項與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, "&nbsp; &nbsp;");   } 
    } 
} 
0
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(); StatusHandler在每次找到文檔時都會調用OnFound,如果文檔未找到,則OnFound方法不會執行,因此不會再載入。

+0

歡迎使用StackOverflow!儘管您發佈的代碼可能很好地回答了問題,但請添加一些解釋。 – trincot

+0

請在您的回答中添加(編輯它),而不是在評論中。 – trincot

相關問題