Python SAX محلل مقابل python DOM محلل. Parsim FIAS- المنازل

في مقال سابق ، درسنا طريقة لإنشاء ملف بتنسيق csv من xml في قاعدة بيانات تم نشرها بواسطة FIAS. اعتمد التحليل على محلل DOM ، الذي يقوم بتحميل الملف بأكمله في الذاكرة قبل المعالجة ، مما أدى إلى الحاجة إلى تقسيم الملفات الكبيرة نظرًا لمقدار ذاكرة الوصول العشوائي المحدود. يُقترح في هذه المرة معرفة مدى جودة محلل SAX ومقارنته مع محلل DOM. سيتم استخدام أكبر حجم من ملفات قاعدة بيانات FIAS ، المنازل ، بحجم 27.5 جيجابايت ، كموضوع اختبار.

دخول


نحن مضطرون إلى إزعاج الجمهور الأكثر احتراماً على الفور - فشل على الفور في تغذية ملف قاعدة بيانات المنازل FIX إلى محلل SAX. تعطل المحلل مع الخطأ "غير جيد التشكيل (رمز غير صالح)". وفي البداية كانت هناك شكوك بأن ملف قاعدة البيانات قد تم كسره. ومع ذلك ، بعد قطع قاعدة البيانات إلى عدة أجزاء صغيرة ، تبين أن المغادرين كانت ناتجة عن تغيير الترميز لأرقام المنازل و / أو المباني. أي أن علامات STRUCNUM أو HOUSENUM صادفت المنازل بحرف مكتوب بترميز غريب (وليس UTF-8 وليس ANSI ، حيث تم تكوين المستند نفسه):



في الوقت نفسه ، إذا تمت تسوية هذا الترميز عن طريق تشغيل الملف من خلال وظيفة remove_non_ascii ، فإن الإدخال يأخذ النموذج



لم يتم استيعاب هذا الملف من قبل المحلل اللغوي بسبب الأحرف الزائدة.

اضطررت إلى تذكر التعبيرات العادية وتنظيف الملف قبل تحميله في المحلل اللغوي.
السؤال: لماذا من المستحيل إنشاء قاعدة بيانات عادية ، والتي وضعت للعمل تكتسب الظل الخطابي.

لمواءمة قدرات بدء المحلل اللغوي ، نقوم بمسح جزء الاختبار من التناقضات المذكورة أعلاه.

رمز لمسح ملف قاعدة البيانات قبل تحميله في المحلل اللغوي:

قانون
from datetime import datetime import re from unidecode import unidecode start = datetime.now() f= open('AS_HOUSE.462.xml', 'r',encoding='ANSI') def remove_non_ascii(text): return unidecode(unidecode(text)) for line in f: b=remove_non_ascii(line) for c in re.finditer(r'\w{5}NUM="\d{1,}\"\w\"',b): print(c[0]) c1=c[0][:-3]+c[0][-2] print(c1) b=b.replace(c[0],c1) #    #  f1= open('out.xml', 'w',encoding='ANSI') f1.write(b) f1.close() f.close() print(datetime.now()- start) 


يترجم الكود الأحرف غير الساسكية إلى العادي في ملف xml ثم يزيل "" غير الضرورية في أسماء المباني والمنازل.

محلل ساكس


للبدء ، خذ ملف xml صغيرًا (58.8 ميغابايت) ، نخطط للحصول على نص أو ملف بتنسيق csv في المخرجات ، وهو مناسب لمزيد من المعالجة في الباندا أو التفوق.

قانون
 import xml.sax import csv from datetime import datetime start = datetime.now() class EventHandler(xml.sax.ContentHandler): def __init__(self,target): self.target = target def startElement(self,name,attrs): self.target.send(attrs._attrs.values()) def characters(self,text): self.target.send('') def endElement(self,name): self.target.send('') def coroutine(func): def start(*args,**kwargs): cr = func(*args,**kwargs) cr.__next__() return cr return start with open('out.csv', 'a') as f: # example use if __name__ == '__main__': @coroutine def printer(): while True: event = (yield) print(event,file=f) xml.sax.parse("out.xml", EventHandler(printer())) print(datetime.now()- start) 


بعد تنفيذ البرنامج ، نحصل على قيم قاموس بايثون:



المهلة الزمنية: 5-6 ثانية.

محلل DOM


نقوم بمعالجة نفس الملف عن طريق تحميله أولاً بالكامل في الذاكرة. هذا هو بالضبط الطريقة التي يستخدمها محلل DOM.

قانون
 import codecs,os import xml.etree.ElementTree as ET import csv from datetime import datetime parser = ET.XMLParser(encoding="ANSI") tree = ET.parse("out.xml",parser=parser) root = tree.getroot() Resident_data = open('AS_HOUSE.0001.csv', 'a',encoding='ANSI') csvwriter = csv.writer(Resident_data) attr_names = [ 'HOUSEID', 'HOUSEGUID', 'AOGUID', 'HOUSENUM', 'STRUCNUM', 'STRSTATUS', 'ESTSTATUS', 'STATSTATUS', 'IFNSFL', 'IFNSUL', 'TERRIFNSFL', 'TERRIFNSUL', 'OKATO', 'OKTMO', 'POSTALCODE', 'STARTDATE', 'ENDDATE', 'UPDATEDATE', 'COUNTER', 'NORMDOC', 'DIVTYPE', 'REGIONCODE' ] start = datetime.now() object = [] for member in root.findall('House'): object = [member.attrib.get(attr_name, None) for attr_name in attr_names] csvwriter.writerow(object) Resident_data.close() print(datetime.now()- start) 


مهلة 2-3 ثانية.
الفوز محلل DOM؟

ملفات أكبر


الملفات الصغيرة لا تعكس الواقع بالكامل. لنأخذ ملفًا أكبر من 353 ميغابايت (بعد التنظيف ، كما هو موضح أعلاه).

نتائج الكتف:

محلل SAX: 0: 00: 32.090836 - 32 ثانية
محلل DOM: 0: 00: 16.630951 - 16 ثانية

الفرق هو 2 مرات السرعة. ومع ذلك ، هذا لا ينتقص من الميزة الرئيسية لمحلل SAX - القدرة على معالجة الملفات الكبيرة دون تحميلها أولاً في الذاكرة.
يبقى أن نأسف لأن هذه الميزة لا تنطبق على قاعدة بيانات FIAS ، لأن العمل التمهيدي مع الترميزات مطلوب.

ملف للتنظيف الأولي للترميزات:
- 353 ميغابايت في الأرشيف .

ملف DB تنقية للاختبارات محلل:
- 353 ميغابايت في الأرشيف .

Source: https://habr.com/ru/post/ar469995/


All Articles