2011-12-03 2 views
1

우리는 서로 용어집 용어 지금 1 개, 2 개 또는 3 개의 단어 (중 공백 또는 대시)로 구분.HTML 문서 내부 용어 사전을 강조

으로 구성 될 수있다 최대 2000 용어와 용어를 (이 우리는 강조 조건을 정적 HTML 페이지를 생성 하기 위해 (최대 1백킬로바이트 HTML 마크 업)을 (이상) HTML 문서 내부의 모든 측면을 강조하기위한 솔루션을 찾고있다.

작업에 대한 제약 해결책은 다음과 같습니다. 많은 용어집 용어 과 긴 HTML 문서 ... 효율적인 해결책을위한 청사진 (파이썬 내).

지금은 lxml을 사용하여 HTML 문서를 구문 분석하고 모든 텍스트 노드를 반복 한 다음 각 텍스트 노드의 내용을 모든 용어 용어와 대조하는 방법을 고려하고 있습니다.

IE에서 스크립트가 만료 된 스크립트에 대해 불평 할 것이므로 클라이언트 측 (브라우저) 강조 표시는 옵션이 아닙니다 ... 프로덕션 용도로는 사용할 수 없으므로.

더 좋은 아이디어가 있습니까?

+0

구문 분석을 위해 아름다운 수프를 확인하고 싶을 수도 있습니다. –

+0

사실을 설명하고 대답하지 않은 것은 실제로 적절한 대답을 쓸 수 있도록 충분한 시간을 내 손안에 가지고 있었음을 지적해야합니다. 아래를 참조하십시오. –

+0

하나의 루프에서 클라이언트 측 하이라이트를 수행 할 필요가 없습니다. 공동 시간 루틴을 시뮬레이트하려면 setTimeout을 사용하십시오. – Dykam

답변

-1

용어집에서 각 용어를 살펴본 다음 각 용어에 대해 정규식을 사용하여 HTML의 모든 항목을 찾으십시오. 이러한 각각의 발생을 배경색을 갖도록 스타일이 지정 될 "강조 표시된"클래스로 스팬 내에 래핑 된 용어로 바꿀 수 있습니다.

+0

그런 다음 용어집 용어가 페이지의 제목이나 meta (예상 가능) 또는 그보다 더 나쁜 경우, 문서 자체가 HTML에 관한 것이고 "form"이 용어집 인 경우 어떻게됩니까? –

+0

좋은 지적. 정규식은 "<>"로 묶인 것을 고려하지 않음으로써 요소를 설명 할 수 있습니다. –

+1

내가 주장을 사과드립니다,하지만 HTML을 구문 분석하는 정규식을 사용하면 [나쁜 생각] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/ 1732454 # 1732454). 무엇보다 문제가 매우 간단하지 않으면 (어떤 경우가 여기에 해당 될 수도 있고 그렇지 않을 수도 있음), 정규 표현식 마에스트라가 아니라면 아마 제대로되지 않을 것입니다. HTML ** 구문 분석은 ** 해결 된 문제이므로 적절한 도구를 사용해야합니다. –

2

파서를 사용하여 재귀 적 방식으로 트리를 탐색하고 텍스트로 구성된 태그 만 바꿀 수 있습니다.
그래도 다음과 같은 사항을 고려해야합니다.
- 모든 텍스트를 교체해야하는 것은 아닙니다 (예 : 인라인 자바 스크립트)
- 문서의 일부 요소는 구문 분석 할 필요가 없습니다 (예 : 제목 등)

여기에 당신이 얻을 수있는 방법에 대한 신속하고 비 생산 준비 예입니다 :

html = """The HTML you need to parse""" 
import BeautifulSoup 

IGNORE_TAGS = ['script', 'style'] 

def parse_content(item, replace_what, replace_with, ignore_tags = IGNORE_TAGS): 
    for content in item.contents: 
     if isinstance(content, BeautifulSoup.NavigableString): 
      content.replaceWith(content.replace(replace_what, replace_with, ignore_tags)) 
     else: 
      if content.name not in ignore_tags: 
       parse_content(content, replace_what, replace_with, ignore_tags) 
    return item 

soup = BeautifulSoup.BeautifulSoup(html) 
body = soup.html.body 
replaced_content = parse_content(body, 'a', 'b') 

이는 "A"는 "B"로, 그러나 떠나는 내용의 선두로부터 교체해야 즉 :
- 내부 인라인 자바 스크립트 또는 CSS (인라인 JS 또는 CSS는 문서 본문에 나타나서는 안됩니다.
- 같은 IMG와 같은 태그에서 참조하는 ...
- 태그 자체

물론, 당신은 필요, 당신의 용어에 따라, 당신은 단지 부품을 교체하지 않는 것이 있는지 확인하는 것입니다 뭔가 다른 단어로; 이렇게하려면 regex insted of content.replace를 사용하는 것이 좋습니다.

0

클라이언트 쪽 자바 스크립트로 강조 표시하는 것이 가장 좋은 방법이라고 생각합니다. 서버 처리 시간과 대역폭을 절약 할 수 있으며 인쇄 또는 다른 형식으로 변환 할 때와 같이 불필요한 마크 업이 필요하지 않은 사용자에게 html을 깨끗하게 유지할 수 있습니다.

시간 초과를 피하려면 작업을 청크로 분할하고 setTimeout에 스레드 된 함수에서 하나씩 처리하십시오.다음은이 방법의 예

function hilite(terms, chunkSize) { 

    // prepare stuff 

    var terms = new RegExp("\\b(" + terms.join("|") + ")\\b", "gi"); 

    // collect all text nodes in the document 

    var textNodes = []; 
    $("body").find("*").contents().each(function() { 
     if (this.nodeType == 3) 
      textNodes.push(this) 
    }); 

    // process N text nodes at a time, surround terms with text "markers" 

    function step() { 
     for (var i = 0; i < chunkSize; i++) { 
      if (!textNodes.length) 
       return done(); 
      var node = textNodes.shift(); 
      node.nodeValue = node.nodeValue.replace(terms, "\x1e$&\x1f"); 
     } 
     setTimeout(step, 100); 
    } 

    // when done, replace "markers" with html 

    function done() { 
     $("body").html($("body").html(). 
      replace(/\x1e/g, "<b>"). 
      replace(/\x1f/g, "</b>") 
     ); 
    } 

    // let's go 

    step() 
} 

이처럼 사용이다 :

$(function() { 
    hilite(["highlight", "these", "words"], 100) 
}) 

당신은 질문이 있으면 알려주세요.