lxml의 태그 안의 모든 텍스트 가져 오기
<content>
코드 태그를 포함하여 아래 세 가지 인스턴스 모두에서 태그 내부의 모든 텍스트 를 lxml로 가져 오는 코드 조각을 작성하고 싶습니다 . 나는 시도 tostring(getchildren())
했지만 태그 사이의 텍스트를 놓칠 것입니다. API에서 관련 기능을 검색하는 데 큰 행운이 없었습니다. 좀 도와 주 시겠어요?
<!--1-->
<content>
<div>Text inside tag</div>
</content>
#should return "<div>Text inside tag</div>
<!--2-->
<content>
Text with no tag
</content>
#should return "Text with no tag"
<!--3-->
<content>
Text outside tag <div>Text inside tag</div>
</content>
#should return "Text outside tag <div>Text inside tag</div>"
시험:
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("""<content>
Text outside tag <div>Text <em>inside</em> tag</div>
</content>""")
stringify_children(node)
생성 : '\nText outside tag <div>Text <em>inside</em> tag</div>\n'
text_content () 가 필요한 작업을 수행 합니까 ?
다음 node.itertext()
과 같이 방법을 사용하십시오 .
''.join(node.itertext())
파이썬 생성기를 사용하는 다음 스 니펫은 완벽하게 작동하며 매우 효율적입니다.
''.join(node.itertext()).strip()
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)
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('<content>').rstrip('</')
스트립 방법을 사용하는 마지막 줄은 좋지 않지만 작동합니다.
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로 남겨 둡니다. tail
의 일부node
이 경우 종료 태그 "뒤에"있기 때문에 흥미롭지 않습니다. 있습니다 encoding
인수가 하나의 필요에 따라 변경 될 수 있습니다.
또 다른 가능한 해결책은 노드 자체를 직렬화하고 나중에 시작 및 종료 태그를 제거하는 것입니다.
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]
다소 끔찍합니다. 이 코드는node
has no attributes, and I don't think anyone would want to use it even then.
실제로 저에게 효과적 이며 http://lxml.de/tutorial.html#using-xpath-to-find-text의 문서에 따라 실제로 작동했던 가장 간단한 코드 조각 중 하나는 다음과 같습니다.
etree.tostring(html, method="text")
where etree is a node/tag whose complete text, you are trying to read. Behold that it doesn't get rid of script and style tags though.
In response to @Richard's comment above, if you patch stringify_children to read:
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])
it seems to avoid the duplication he refers to.
I know that this is an old question, but this is a common problem and I have a solution that seems simpler than the ones suggested so far:
def stringify_children(node):
"""Given a LXML tag, return contents as a string
>>> html = "<p><strong>Sample sentence</strong> with tags.</p>"
>>> node = lxml.html.fragment_fromstring(html)
>>> extract_html_content(node)
"<strong>Sample sentence</strong> 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]
Unlike some of the other answers to this question this solution preserves all of tags contained within it and attacks the problem from a different angle than the other working solutions.
Here is a working solution. We can get content with a parent tag and then cut the parent tag from output.
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
must have Element
type.
Please note, that if you want text content (not html entities in text) please leave html_entities
parameter as False.
lxml have a method for that:
node.text_content()
If this is an a tag, you can try:
node.values()
import re
from lxml import etree
node = etree.fromstring("""
<content>Text before inner tag
<div>Text
<em>inside</em>
tag
</div>
Text after inner tag
</content>""")
print re.search("\A<[^<>]*>(.*)</[^<>]*>\Z", etree.tostring(node), re.DOTALL).group(1)
참고URL : https://stackoverflow.com/questions/4624062/get-all-text-inside-a-tag-in-lxml
'IT박스' 카테고리의 다른 글
iOS UISearchBar에서 검색 (입력 속도 기준)을 제한하는 방법은 무엇입니까? (0) | 2020.11.16 |
---|---|
Jest 캐시를 지우는 방법? (0) | 2020.11.16 |
여러 @ControllerAdvice @ExceptionHandlers의 우선 순위 설정 (0) | 2020.11.16 |
Visual Studio“파일 또는 어셈블리를로드 할 수 없습니다. (0) | 2020.11.16 |
Typescript를 사용할 때 "property does not exist on type JQuery"구문 오류를 어떻게 막을 수 있습니까? (0) | 2020.11.16 |