<질문>
내부의 모든 텍스트를 가져 오는 코드 스 니펫을 작성하고 싶습니다.
Text inside tag
#should return "Text inside tag
Text with no tag
#should return "Text with no tag"
Text outside tag Text inside tag
#should return "Text outside tag Text inside tag"
<답변1>
시험:
def stringify_children(node):
from lxml.etree import tostring
from itertools import chain
parts = ([node.text] +
list(chain(*([c.text, tostring(c), c.tail] for c in node.getchildren()))) +
[node.tail])
# filter removes possible Nones in texts and tails
return ''.join(filter(None, parts))
예:
from lxml import etree
node = etree.fromstring("""
Text outside tag Text inside tag
""")
stringify_children(node)
생성 : '\ n 태그 외부 텍스트
<답변2>
text_content ()가 필요한 작업을 수행합니까?
<답변3>
다음과 같이 node.itertext () 메서드를 사용하십시오.
''.join(node.itertext())
<답변4>
파이썬 생성기를 사용하는 다음 스 니펫은 완벽하게 작동하며 매우 효율적입니다.
''.join (node.itertext ()). strip ()
<답변5>
hoju가보고 한 버그를 해결하는 albertov의 stringify-content 버전 :
def stringify_children(node):
from lxml.etree import tostring
from itertools import chain
return ''.join(
chunk for chunk in chain(
(node.text,),
chain(*((tostring(child, with_tail=False), child.tail) for child in node.getchildren())),
(node.tail,)) if chunk)
<답변6>
이런 식으로 stringify_children을 정의하는 것은 덜 복잡 할 수 있습니다.
from lxml import etree
def stringify_children(node):
s = node.text
if s is None:
s = ''
for child in node:
s += etree.tostring(child, encoding='unicode')
return s
또는 한 줄로
return (node.text if node.text is not None else '') + ''.join((etree.tostring(child, encoding='unicode') for child in node))
이론적 근거는이 답변과 동일합니다. 자식 노드의 직렬화를 lxml로 남겨 둡니다. 이 경우 노드의 꼬리 부분은 종료 태그 "뒤"에 있으므로 흥미롭지 않습니다. 인코딩 인수는 필요에 따라 변경 될 수 있습니다.
또 다른 가능한 해결책은 노드 자체를 직렬화하고 나중에 시작 및 종료 태그를 제거하는 것입니다.
def stringify_children(node):
s = etree.tostring(node, encoding='unicode', with_tail=False)
return s[s.index(node.tag) + 1 + len(node.tag): s.rindex(node.tag) - 2]
다소 끔찍합니다. 이 코드는 노드에 속성이없는 경우에만 정확하며, 그때에도 아무도 사용하고 싶지 않을 것이라고 생각합니다.
<답변7>
import urllib2
from lxml import etree
url = 'some_url'
URL 가져 오기
test = urllib2.urlopen(url)
page = test.read()
테이블 태그를 포함하여 모든 HTML 코드 가져 오기
tree = etree.HTML(page)
xpath 선택기
table = tree.xpath("xpath_here")
res = etree.tostring(table)
res는 이것이 나를 위해 일하는 테이블의 html 코드입니다.
따라서 xpath_text ()로 태그 내용을 추출하고 tostring ()을 사용하여 내용을 포함하는 태그를 추출 할 수 있습니다.
div = tree.xpath("//div")
div_res = etree.tostring(div)
text = tree.xpath_text("//content")
또는 text = tree.xpath ( "// content / text ()")
div_3 = tree.xpath("//content")
div_3_res = etree.tostring(div_3).strip('').rstrip('')
스트립 방법을 사용하는 마지막 줄은 좋지 않지만 작동합니다.
<답변8>
위의 @Richard의 의견에 대한 응답으로 stringify_children을 패치하면 다음을 읽을 수 있습니다.
parts = ([node.text] +
-- list(chain(*([c.text, tostring(c), c.tail] for c in node.getchildren()))) +
++ list(chain(*([tostring(c)] for c in node.getchildren()))) +
[node.tail])
그가 언급 한 중복을 피하는 것 같습니다.
<답변9>
실제로 저에게 도움이되었으며 http://lxml.de/tutorial.html#using-xpath-to-find-text의 문서에 따라 실제로 작동 한 가장 간단한 코드 조각 중 하나는 다음과 같습니다.
etree.tostring(html, method="text")
여기서 etree는 전체 텍스트를 읽으려는 노드 / 태그입니다. 그래도 스크립트 및 스타일 태그를 제거하지 않습니다.
<답변10>
나는 이것이 오래된 질문이라는 것을 알고 있지만 이것은 일반적인 문제이며 지금까지 제안한 것보다 더 간단한 해결책이 있습니다.
def stringify_children(node):
"""Given a LXML tag, return contents as a string
>>> html = "Sample sentence with tags.
"
>>> node = lxml.html.fragment_fromstring(html)
>>> extract_html_content(node)
"Sample sentence with tags."
"""
if node is None or (len(node) == 0 and not getattr(node, 'text', None)):
return ""
node.attrib.clear()
opening_tag = len(node.tag) + 2
closing_tag = -(len(node.tag) + 3)
return lxml.html.tostring(node)[opening_tag:closing_tag]
이 질문에 대한 다른 답변과 달리이 솔루션은 그 안에 포함 된 모든 태그를 보존하고 다른 작업 솔루션과 다른 각도에서 문제를 공격합니다.
<답변11>
다음은 작동하는 솔루션입니다. 부모 태그가있는 콘텐츠를 가져온 다음 출력에서 부모 태그를 잘라낼 수 있습니다.
import re
from lxml import etree
def _tostr_with_tags(parent_element, html_entities=False):
RE_CUT = r'^<([\w-]+)>(.*)([\w-]+)>$'
content_with_parent = etree.tostring(parent_element)
def _replace_html_entities(s):
RE_ENTITY = r'(\d+);'
def repl(m):
return unichr(int(m.group(1)))
replaced = re.sub(RE_ENTITY, repl, s, flags=re.MULTILINE|re.UNICODE)
return replaced
if not html_entities:
content_with_parent = _replace_html_entities(content_with_parent)
content_with_parent = content_with_parent.strip() # remove 'white' characters on margins
start_tag, content_without_parent, end_tag = re.findall(RE_CUT, content_with_parent, flags=re.UNICODE|re.MULTILINE|re.DOTALL)[0]
if start_tag != end_tag:
raise Exception('Start tag does not match to end tag while getting content with tags.')
return content_without_parent
parent_element에는 요소 유형이 있어야합니다.
텍스트 콘텐츠 (텍스트의 html 엔티티가 아님)를 원하는 경우 html_entities 매개 변수를 False로 두십시오.
<답변12>
lxml에는 다음과 같은 방법이 있습니다.
node.text_content()
<답변13>
대답이 주어 졌을 때 빠르게 향상되었습니다. 내부 텍스트를 정리하려면 :
clean_string = ' '.join([n.strip() for n in node.itertext()]).strip()
<답변14>
태그 인 경우 다음을 시도 할 수 있습니다.
node.values()
<답변15>
import re
from lxml import etree
node = etree.fromstring("""
Text before inner tag
Text
inside
tag
Text after inner tag
""")
print re.search("\A<[^<>]*>(.*)[^<>]*>\Z", etree.tostring(node), re.DOTALL).group(1)
'개발 > Python' 카테고리의 다른 글
파이썬을 사용하여 실제 사용자 홈 디렉토리를 찾는 방법은 무엇입니까? (0) | 2020.09.19 |
---|---|
Python ElementTree를 문자열로 변환 (0) | 2020.09.19 |
목록의 모든 항목이 없음인지 확인하는 방법은 무엇입니까? (0) | 2020.09.19 |
pip를 사용하여 pylibmc를 설치할 때 오류 발생 (0) | 2020.09.19 |