2010-11-01 27 views
11

He escrito un script simple para analizar los registros de chat XML utilizando el módulo BeautifulSoup. El estándar soup.prettify() funciona bien, excepto que los registros de chat tienen mucha pelusa. Se puede ver tanto el código de secuencia de comandos y algunos de los archivos de entrada XML que estoy trabajando a continuación:Python BeautifulSoup XML Parsing

Código

import sys 
from BeautifulSoup import BeautifulSoup as Soup 

def parseLog(file): 
    file = sys.argv[1] 
    handler = open(file).read() 
    soup = Soup(handler) 
    print soup.prettify() 

if __name__ == "__main__": 
    parseLog(sys.argv[1]) 

de entrada XML de prueba

<?xml version="1.0"?> 
<?xml-stylesheet type='text/xsl' href='MessageLog.xsl'?> 
<Log FirstSessionID="1" LastSessionID="2"><Message Date="10/31/2010" Time="3:43:48 PM"  DateTime="2010-10-31T20:43:48.937Z" SessionID="1"><From><User FriendlyName="Jon"/></From> <To><User FriendlyName="Bill"/></To><Text Style="font-family:Segoe UI; color:#000000; ">hey, what's up?</Text></Message> 
<Message Date="10/31/2010" Time="3:44:03 PM" DateTime="2010-10-15T20:44:03.421Z" SessionID="1"><From><User FriendlyName="Jon"/></From><To><User FriendlyName="Bill"/></To><Text Style="font-family:Segoe UI; color:#000000; ">Got your message</Text></Message> 
<Message Date="10/31/2010" Time="3:44:31 PM" DateTime="2010-10-15T20:44:31.390Z" SessionID="2"><From><User FriendlyName="Bill"/></From><To><User FriendlyName="Jon"/></To><Text Style="font-family:Segoe UI; color:#000000; ">oh, great</Text></Message> 
<Message Date="10/31/2010" Time="3:44:59 PM" DateTime="2010-10-15T20:44:59.281Z" SessionID="2"><From><User FriendlyName="Bill"/></From><To><User FriendlyName="Jon"/></To><Text Style="font-family:Segoe UI; color:#000000; ">hey, i gotta run</Text></Message> 

estoy querer poder mostrar esto en un formato como el siguiente o al menos algo que sea más legible que XML puro:

Jon: Oye, ¿qué pasa? [10/31/10 @ 3: 43p]

Jon: conseguido su mensaje [10/31/10 @ 3: 44p]

Bill: oh, gran [10/31/10 @ 3 : 44p]

etc. He oído algunas cosas decentes sobre el módulo PyParsing, tal vez es hora de darle una oportunidad.

+1

¿Por qué no XSLT? Eso sería lo más fácil. (De hecho: veo que hay una directiva de xml-stylesheet: ¿cómo se ve la hoja de estilos predeterminada?) –

+0

Puede que no siempre tenga disponible la hoja de estilos XSL, por lo que es necesario algo para formatear el registro en algo un poco más legible . Si puedo usar la misma hoja de estilo que tengo, eso también podría funcionar. –

Respuesta

24

BeautifulSoup hace que obtener atributos y valores en xml sea realmente simple. Ajusté tu función de ejemplo para usar estas funciones.

import sys 
from BeautifulSoup import BeautifulSoup as Soup 

def parseLog(file): 
    file = sys.argv[1] 
    handler = open(file).read() 
    soup = Soup(handler) 
    for message in soup.findAll('message'): 
     msg_attrs = dict(message.attrs) 
     f_user = message.find('from').user 
     f_user_dict = dict(f_user.attrs) 
     print "%s: %s [%s @ %s]" % (f_user_dict[u'friendlyname'], 
            message.find('text').decodeContents(), 
            msg_attrs[u'date'], 
            msg_attrs[u'time']) 


if __name__ == "__main__": 
    parseLog(sys.argv[1]) 
+1

Esto funciona perfectamente. ¿Qué es exactamente lo que figura en el diccionario de f_user_dict = dict (f_user.attrs) Supongo que los atributos, tendré que jugar con esa pieza y ver exactamente lo que hay allí. ¡Gracias de nuevo! –

+0

Sí, para todos los elementos, el.attrs contendrá una lista de tuplas de los atributos de las etiquetas xml. Llamar a dict en cualquier tupla lo convertirá en un diccionario. – dcolish

+1

Oh, solo quería aclarar, llamar a dict en una lista de tuplas devolverá un diccionario, ni una sola tupla: dict ([('hello', 'adiós'), ('foo', 'bar')]) – dcolish

6

Recomendaría utilizar el módulo integrado ElementTree. BeautifulSoup está diseñado para manejar código mal formado como HTML pirateado, mientras que XML está bien formado y debe ser leído por una biblioteca XML.

Actualización: algunas de mis lecturas recientes sugieren que lxml es una biblioteca integrada y mejora el ElementTree estándar.

+6

Uso Beautiful Soup para analizar XML. De los documentos: "Beautiful Soup es una biblioteca de Python para extraer datos de archivos HTML y XML". Beautiful Soup usará cualquier analizador que se lo indique, incluido lxml. (ver http://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser) – lfalin

+0

Y he visto un montón de cadenas XML malformados últimamente. – whatnick