[PYTHON] XML 요소를 통해 반복하는 효율적인 방법
PYTHONXML 요소를 통해 반복하는 효율적인 방법
나는 이런 식으로 XML을 가지고 :
<a>
<b>hello</b>
<b>world</b>
</a>
<x>
<y></y>
</x>
<a>
<b>first</b>
<b>second</b>
<b>third</b>
</a>
모든 및 태그를 반복해야하지만 문서에 얼마나 많은 태그가 있는지 모릅니다. 그래서 그것을 처리하는 xpath 사용 :
from lxml import etree
doc = etree.fromstring(xml)
atags = doc.xpath('//a')
for a in atags:
btags = a.xpath('b')
for b in btags:
print b
그것은 작동하지만 꽤 큰 파일을 가지고 있고, cProfile은 xpath가 사용하기에 매우 비쌉니다.
아마도 무한히 많은 xml 요소를 반복하는 효율적인 방법이 있을까요?
해결법
-
==============================
1.XPath는 빠릅니다. XPath 호출 수를 1로 줄일 수 있습니다.
XPath는 빠릅니다. XPath 호출 수를 1로 줄일 수 있습니다.
doc = etree.fromstring(xml) btags = doc.xpath('//a/b') for b in btags: print b.text
그렇게 빠르지 않으면 Liza Daly의 fast_iter를 시도해 볼 수 있습니다. 이것은 우선 전체 XML을 etree.fromstring으로 처리 할 필요가 없다는 장점이 있으며, 부모 노드는 자식을 방문한 후에 버려집니다. 이 두 가지 모두 메모리 요구 사항을 줄이는 데 도움이됩니다. 다음은 더 이상 필요없는 다른 요소를 제거하는 데 더 적극적인 fast_iter의 수정 된 버전입니다.
def fast_iter(context, func, *args, **kwargs): """ fast_iter is useful if you need to free memory while iterating through a very large XML file. http://lxml.de/parsing.html#modifying-the-tree Based on Liza Daly's fast_iter http://www.ibm.com/developerworks/xml/library/x-hiperfparse/ See also http://effbot.org/zone/element-iterparse.htm """ for event, elem in context: func(elem, *args, **kwargs) # It's safe to call clear() here because no descendants will be # accessed elem.clear() # Also eliminate now-empty references from the root node to elem for ancestor in elem.xpath('ancestor-or-self::*'): while ancestor.getprevious() is not None: del ancestor.getparent()[0] del context def process_element(elt): print(elt.text) context=etree.iterparse(io.BytesIO(xml), events=('end',), tag='b') fast_iter(context, process_element)
큰 XML 파일을 파싱하는 Liza Daly의 기사가 여러분에게 유용한 읽을 거리가 될 것입니다. 이 기사에 따르면 fast_iter가있는 lxml은 cElementTree의 iterparse보다 빠를 수 있습니다. (표 1 참조).
-
==============================
2.iter는 어때?
iter는 어때?
>>> for tags in root.iter('b'): # root is the ElementTree object ... print tags.tag, tags.text ... b hello b world b first b second b third
-
==============================
3.iterparse 사용 :
iterparse 사용 :
import lxml.etree as ET for event, elem in ET.iterparse(filelike_object): if elem.tag == "a": process_a(elem) for child in elem: process_child(child) elem.clear() # destroy all child elements elif elem.tag != "b": elem.clear()
이것은 모든 메모리를 저장하지는 않지만이 기술을 사용하여 GB 이상의 XML 스트림을 탐색 할 수있었습니다.
import xml.etree.cElementTree를 ET로 사용해보십시오 ... lxml docs에 따르면, it는 Python과 함께 제공되며 iterparse는 lxml.etree iterparse보다 빠릅니다.
큰 파일의 높은 파서 처리량이 필요하고 직렬화가 거의 필요없는 응용 프로그램의 경우 cET가 가장 좋습니다. 소량의 데이터를 추출하거나 그렇지 않은 대형 XML 데이터 집합에서 정보를 집계하는 iterparse 응용 프로그램의 경우 " 그러나 라운드 트립 성능의 경우 lxml은 여러 번 더 빠르다는 경향이 있으므로 입력 문서가 출력보다 크게 나오지 않으면 lxml이 확실한 승자가됩니다. ""
-
==============================
4.bs4는이 작업에 매우 유용합니다.
bs4는이 작업에 매우 유용합니다.
from bs4 import BeautifulSoup raw_xml = open(source_file, 'r') soup = BeautifulSoup(raw_xml) soup.find_all('tags')
from https://stackoverflow.com/questions/4695826/efficient-way-to-iterate-throught-xml-elements by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬 함수에 동적으로 추가 (0) | 2018.10.24 |
---|---|
[PYTHON] 가져 오기 오류 : 'No module named'* does * exist (0) | 2018.10.24 |
[PYTHON] 파이썬을 이용한 이미지 컬러 검출 (0) | 2018.10.24 |
[PYTHON] 파이썬에서 Windows 환경 변수를 수정하기위한 인터페이스 (0) | 2018.10.24 |
[PYTHON] Django 달 단위로 그룹화 주석 달기 (0) | 2018.10.24 |