python報文解析
Ⅰ 如何使用python解析超大XML文檔
在工作時最有吸引力的地方在於可以盡量避免使用昔日的技術。主機、租用線路、COBOL語言......沒有人應該要處理這些東西了,對不對?不幸的是,你最終會與現實發生沖突,即使是2014年,大家都知道JSON是最好的方式,你的票務供應商(你無法控制的)會告訴你,只有使用XML導出才能讓大容量的數據輸出他們的系統。
唉~~~~,好,很好,無所謂。這只是一次性的事情,我不需要照顧和養活這個XML,我只需要解析它並將數據保存到Postgres中,我們就可以利用它。不應該太困難,我需要寫一點python腳本…
import xml.etree.cElementTree as ET
tree = ET.parse('huge.xml')
for ticket_node in tree.findall('ticket'):
#etc...
......這將工作的非常好,如果我們談論的是一個幾MB的XML文檔,但是如果遇到的是huge.xml它是1.3GB的巨大文檔,這種方法只會融化你的筆記本電腦(以16GB的MacBookPro,一旦python的過程花了超過約3GB的內存,系統變得幾乎完全反應遲鈍,並且它幾乎還沒有完成)。回到原點。
首先讓我們快速瀏覽一下我們的數據。
<?xml version="1.0" encoding="UTF-8"?>
<tickets report_date="20140217">
<ticket>
<!-- various ticket fields, some of which I want -->
<comments type="array">
<comment>
<!-- various comment fields, some of which I want -->
</comment>
<!-- possibly more comment tags -->
</comments>
</ticket>
<!-- many, many ticket tags -->
</tickets>
不是很復雜,作為一個整體它不是一個真正的文件中,<ticket>節點只是一個列表,每一類又是一個小文件,我想挑出幾部分出來。我不需要做針對樹的任何復雜的遍歷,只是希望從每個<ticket>節點獲得一些數據然後把它扔掉再讀下一個。原來ElementTree的對眼前這個場景提供了一個工具:iterparse()。讓我們再試一次:
import xml.etree.cElementTree as ET
for event, element in ET.iterparse('huge.xml'):
if event == 'end' and element.tag == 'ticket':
#process ticket...
…什麼? !我的筆記本電腦又融化了!跟parse-the-whole-file的方法一樣使用了完全相同的內存(和系統響應能力)。到底發生了什麼事?
好吧,稍微google了一下,google告訴我,當iterparse()讀取元素時,它仍然是在內存中建立了一個完整的文檔樹,就像我一開始使用parse()方法一樣。幾個博客和stackoverflow的答案推薦添加element.clear()方法在循環結束時清理你不需要的對象,可以限制內存消耗。我拯救了你的麻煩:它不工作。其他博客,so的答案,甚至一個IBM白皮書表明需要在循環結束時進行更徹底的清掃工作結束:
import lxml.etree as ET #the IBM piece used lxml but I tried cElementTree also
for event, element in ET.iterparse('huge.xml'):
if event == 'end' and element.tag == 'ticket':
#process ticket...
element.clear()
while elem.getprevious() is not None:
del elem.getparent()[0]
......哎呀!我溶化了另一台筆記本電腦!
為什麼不工作?坦率地說,我不知道。
我稍微離題一下來說說為什麼我愛Python。作為一個DBA和系統工程師,我面對著大量的一次性編程挑戰。移動這個從這里到那裡、Munge數據、將數據從這里遷移到哪裡。這種類型的挑戰是非常適合於蠻力編程解決問題的這種方式。總之,有時是不值得在建立一個優雅的、易於維護的解決方案上花費任何時間。有時候,你只需要解決這個問題,然後忘掉它。 在處理這類問題上Python最棒的,簡潔的語法、良好的設計理念、豐富的庫都有助於這個工具,很容易快速解決您碰到的任何問題。即使速度比同等的Java解決方案的10倍還慢,如果需要5分鍾的時間寫而不是5小時,我更願意使用python,因為人類工時比CPU工時更有價值。
所有這一切都證明下述方式解決了我的問題,而不會融化的筆記本電腦:
import xml.etree.cElementTree as ET
def process_buffer(buf):
tnode = ET.fromstring(buf)
#pull it apart and stick it in the database
inputbuffer = ''
with open('huge.xml','rb') as inputfile:
append = False
for line in inputfile:
if '<ticket>' in line:
inputbuffer = line
append = True
elif '</ticket>' in line:
inputbuffer += line
append = False
process_buffer(inputbuffer)
inputbuffer = None
del inputbuffer #probably rendant...
elif append:
inputbuffer += line
不是最優雅,或有效率,或者通用的解決方案,但它可以工作。剛剛看了手邊的手冊,利用其結構的簡單性,在解析之前根據xml文件的內容將它切成可管理的塊,然後解析和處理每個塊,終於可以確保不再需要更長的時間來把它全部處理完。
Ⅱ Python 解析WEB上的JSON數據
python有個包是json的:
#!/usr/local/bin/python
#coding=utf-8
importos
importjsonRes='[{"brief":"ooooo","class_extid":13,"create_time":1131783174,"face_id":4,"flag":6777217,"flag_ext":0,"level":0,"max_member":100,"memo":"m~F~M0m~Zm~@~B","name":"10502","option":2,"ul":[{"flag":4,"u":285},{"flag":4,"u":35}]}]'
qDic=json.loads(Res)
foriinqDic:
printi["class_extid"]
forjini["ul"]:
printstr(j["flag"])+"==="+str(j["u"])
這是一段代碼,試著自己改寫下。
Ⅲ Python 怎麼解析 xml字元串
1. 我上面這段xml代碼,一開始沒有注意看,在每一個元素的結尾元素中都含有轉義符,這就是為什麼我用xml解析插件時一直保報錯的原因,因為他不是正規的xml格式。我的方法是用正則替換掉:re.sub(r'(<)\\(/.+?>)',r'\g<1>\g<2>',f_xml) 對於Python中的正則re的sub用法
2. 處理成正規的xml格式後,我這里還是用ElementTree來解析的,但在載入時又報錯:
cElementTree.ParseError: XML or text declaration not at start of entity: line 2, column 0
這個錯誤我在網上沒有找到合適的答案,不過根據字面意思來解決,就是在開頭的地方有錯誤。這里我嘗試這吧xml的文檔聲明給去掉了,居然沒有報錯。這里有些不理解為什麼不能加? 我的方法:f_xml=test_xml.replace('<?xml version="1.0" encoding="gbk"?>','')
3. 然後再載入,就能獲取到相應的節點了。
Ⅳ Python網路請求和解析json數據
Python 的 json 模塊提供了兩個函數 json.mps() 和 json.loads() 來編碼和解碼JSON數據。
如果要處理的是文件而不是字元串,可以使用 json.mp() 和 json.load() 來編碼和解碼JSON數據。例如:
Ⅳ python3.0怎麼用json從文件解析
1、說明:
python3通過json模塊load函數來解析文件。
2、代碼示例:
首先編寫一個json文件j.txt,內容如下:
{"errno":1,"errmsg":"操作成功!","data":[]}
python代碼如下:
importjson
withopen('j.txt','r')asfr:
o=json.load(fr)
print(o['errno'])
print(o['errmsg'])
print(len(o['data']))
輸出如下:
1
操作成功!
0
3、函數說明:
load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
反序列化fp(一個.read()包含 - 支持類文件對象一個JSON文件),以一個Python對象。
object_hook是將與被調用的可選功能任何對象文本解碼(一個``dict``)的結果。返回值object_hook將用來代替dict。此功能可用於實現自定義解碼器(例如JSON-RPC級提示)。
object_pairs_hook是將與被調用的可選功能任何對象的結果與對的有序列表字面解碼。該的返回值object_pairs_hook將用來代替dict。
此功能可用於實現依賴於定製解碼器命令該鍵和值對被解碼(例如,collections.OrderedDict會記得插入的順序)。如果object_hook也定義了object_pairs_hook優先。
要使用自定義JSONDecoder子類,與cls指定它kwarg;否則JSONDecoder使用。
4、其它說明:
也可以使用json.loads函數來直接處理字元串,方法如下:
o=json.loads('{"errno":0,"errmsg":"操作成功!","data":[]}')