email.parser: Parsning av e-postmeddelanden

Källkod: Lib/email/parser.py


Objektstrukturer för meddelanden kan skapas på två sätt: de kan skapas helt från början genom att skapa ett EmailMessage-objekt, lägga till rubriker med hjälp av dictionary-gränssnittet och lägga till nyttolast(er) med hjälp av set_content() och relaterade metoder, eller så kan de skapas genom att parsa en serialiserad representation av e-postmeddelandet.

Paketet email tillhandahåller en standardparser som förstår de flesta e-postdokumentstrukturer, inklusive MIME-dokument. Du kan skicka ett bytes-, sträng- eller filobjekt till parsern, som returnerar rotobjektet EmailMessage i objektstrukturen. För enkla icke-MIME-meddelanden kommer nyttolasten för detta rotobjekt sannolikt att vara en sträng som innehåller texten i meddelandet. För MIME-meddelanden returnerar rotobjektet True från sin metod is_multipart(), och underdelarna kan nås via metoderna för manipulering av nyttolasten, t.ex. get_body(), iter_parts() och walk().

Det finns faktiskt två parsergränssnitt tillgängliga för användning, Parser API och det inkrementella FeedParser API. API:et Parser är mest användbart om du har hela texten i meddelandet i minnet, eller om hela meddelandet finns i en fil i filsystemet. API:et FeedParser är mer lämpligt när du läser meddelandet från en ström som kan blockeras i väntan på mer indata (t.ex. när du läser ett e-postmeddelande från en socket). FeedParser kan konsumera och analysera meddelandet stegvis och returnerar rotobjektet först när du stänger parsern.

Observera att parsern kan utökas på begränsade sätt, och naturligtvis kan du implementera din egen parser helt från grunden. All logik som kopplar samman email-paketets medföljande parser och EmailMessage-klassen finns i Policy-klassen, så en anpassad parser kan skapa träd av meddelandeobjekt på det sätt som den finner nödvändigt genom att implementera anpassade versioner av lämpliga Policy-metoder.

FeedParser API

BytesFeedParser, som importeras från modulen email.feedparser, tillhandahåller ett API som är lämpligt för stegvis analys av e-postmeddelanden, t.ex. när man läser texten i ett e-postmeddelande från en källa som kan blockeras (t.ex. en socket). API:t BytesFeedParser kan naturligtvis användas för att analysera ett e-postmeddelande som helt och hållet finns i ett bytesliknande objekt, en sträng eller en fil, men API:t BytesParser kan vara mer praktiskt för sådana användningsfall. Semantiken och resultaten för de två parser-API:erna är identiska.

API:et för BytesFeedParser är enkelt; du skapar en instans, matar den med en massa bytes tills det inte finns mer att mata den med och stänger sedan parsern för att hämta rotmeddelandeobjektet. BytesFeedParser är extremt exakt när den analyserar meddelanden som följer standarder, och den gör ett mycket bra jobb med att analysera meddelanden som inte följer standarder, och ger information om hur ett meddelande ansågs vara trasigt. Den kommer att fylla ett meddelandeobjekts defects-attribut med en lista över alla problem som den hittade i ett meddelande. Se modulen email.errors för en lista över defekter som den kan hitta.

Här är API:et för BytesFeedParser:

class email.parser.BytesFeedParser(_factory=None, *, policy=policy.compat32)

Skapa en instans av BytesFeedParser. Valfri _factory är en anropsbar utan argument; om den inte anges används message_factory från policy. Anropa _factory när ett nytt meddelandeobjekt behövs.

Om policy anges används de regler som anges för att uppdatera representationen av meddelandet. Om policy inte anges, använd policyn compat32, som upprätthåller bakåtkompatibilitet med Python 3.2-versionen av e-postpaketet och tillhandahåller Message som standardfabrik. Alla andra policyer tillhandahåller EmailMessage som standard _factory. Mer information om vad mer policy kontrollerar finns i dokumentationen för policy.

Obs: ** Nyckelordet policy ska alltid anges**; Standardvärdet kommer att ändras till email.policy.default i en framtida version av Python.

Tillagd i version 3.2.

Ändrad i version 3.3: Nyckelordet policy har lagts till.

Ändrad i version 3.6: _factory Standardvärdet är policyn message_factory.

feed(data)

Mata parsern med mer data. data bör vara ett bytesliknande objekt som innehåller en eller flera rader. Raderna kan vara partiella och parsern kommer att sy ihop sådana partiella rader på rätt sätt. Raderna kan ha någon av de tre vanliga radavslutningarna: vagnsretur, ny rad eller vagnsretur och ny rad (de kan även blandas).

close()

Slutför parsningen av all tidigare matad data och returnerar rotmeddelandeobjektet. Det är odefinierat vad som händer om feed() anropas efter att denna metod har anropats.

class email.parser.FeedParser(_factory=None, *, policy=policy.compat32)

Fungerar som BytesFeedParser förutom att indata till feed()-metoden måste vara en sträng. Detta är av begränsad nytta, eftersom det enda sättet för ett sådant meddelande att vara giltigt är att det endast innehåller ASCII-text eller, om utf8 är True, inga binära bilagor.

Ändrad i version 3.3: Nyckelordet policy har lagts till.

Parser API

Klassen BytesParser, importerad från modulen email.parser, tillhandahåller ett API som kan användas för att analysera ett meddelande när det fullständiga innehållet i meddelandet finns tillgängligt i ett bytesliknande objekt eller en fil. Modulen email.parser tillhandahåller även Parser för att analysera strängar och analysatorer för enbart rubriker, BytesHeaderParser och HeaderParser, som kan användas om du bara är intresserad av meddelandets rubriker. BytesHeaderParser och HeaderParser kan vara mycket snabbare i dessa situationer, eftersom de inte försöker analysera meddelandetexten, utan istället sätter nyttolasten till den råa texten.

class email.parser.BytesParser(_class=None, *, policy=policy.compat32)

Skapa en instans av BytesParser. Argumenten _class och policy har samma betydelse och semantik som argumenten _factory och policy i BytesFeedParser.

Obs: ** Nyckelordet policy ska alltid anges**; Standardvärdet kommer att ändras till email.policy.default i en framtida version av Python.

Ändrad i version 3.3: Tog bort argumentet strict som inte längre användes i 2.4. Nyckelordet policy har lagts till.

Ändrad i version 3.6: _class Standardvärdet är policyn message_factory.

parse(fp, headersonly=False)

Läser alla data från det binära filliknande objektet fp, analyserar de resulterande byte och returnerar meddelandeobjektet. fp måste stödja både metoderna readline() och read().

Bytesen i fp måste formateras som ett block med rubriker och fortsättningsrader av typen RFC 5322 (eller, om utf8 är True, RFC 6532), eventuellt föregånget av ett kuverthuvud. Huvudblocket avslutas antingen med slutet av datan eller med en blank rad. Efter huvudblocket följer meddelandetexten (som kan innehålla MIME-kodade underdelar, inklusive underdelar med en Content-Transfer-Encoding8bit).

Valfritt headersonly är en flagga som anger om parsningen ska avbrytas efter att rubrikerna har lästs eller inte. Standardvärdet är False, vilket innebär att hela filens innehåll analyseras.

parsebytes(bytes, headersonly=False)

Liknar metoden parse(), förutom att den tar ett bytesliknande objekt istället för ett filliknande objekt. Att anropa denna metod på ett bytesliknande objekt är likvärdigt med att först packa in bytes i en BytesIO-instans och sedan anropa parse().

Valfritt headersonly är som med metoden parse().

Tillagd i version 3.2.

class email.parser.BytesHeaderParser(_class=None, *, policy=policy.compat32)

Exakt som BytesParser, förutom att headersonly som standard är True.

Tillagd i version 3.3.

class email.parser.Parser(_class=None, *, policy=policy.compat32)

Denna klass är parallell med BytesParser, men hanterar stränginmatning.

Ändrad i version 3.3: Argumentet strict har tagits bort. Nyckelordet policy har lagts till.

Ändrad i version 3.6: _class Standardvärdet är policyn message_factory.

parse(fp, headersonly=False)

Läser alla data från det filliknande objektet fp i textläge, tolkar den resulterande texten och returnerar rotmeddelandeobjektet. fp måste stödja både metoderna readline() och read() för filliknande objekt.

Bortsett från kravet på textläge fungerar den här metoden som BytesParser.parse().

parsestr(text, headersonly=False)

Liknar metoden parse(), förutom att den tar ett strängobjekt istället för ett filliknande objekt. Att anropa denna metod på en sträng motsvarar att först packa in text i en StringIO-instans och sedan anropa parse().

Valfritt headersonly är som med metoden parse().

class email.parser.HeaderParser(_class=None, *, policy=policy.compat32)

Exakt som Parser, förutom att headersonly har standardvärdet True.

Eftersom det är en vanlig uppgift att skapa en meddelandeobjektstruktur från en sträng eller ett filobjekt, finns det fyra funktioner som en bekvämlighet. De är tillgängliga i toppnivån email package namespace.

email.message_from_bytes(s, _class=None, *, policy=policy.compat32)

Returnerar en meddelandeobjektstruktur från ett bytesliknande objekt. Detta är likvärdigt med BytesParser().parsebytes(s). Valfria _class och policy tolkas som med BytesParser klasskonstruktören.

Tillagd i version 3.2.

Ändrad i version 3.3: Argumentet strict har tagits bort. Nyckelordet policy har lagts till.

email.message_from_binary_file(fp, _class=None, *, policy=policy.compat32)

Returnerar ett strukturträd för meddelandeobjekt från ett öppet binärt filobjekt. Detta är likvärdigt med BytesParser().parse(fp). _class och policy tolkas som med BytesParser klasskonstruktören.

Tillagd i version 3.2.

Ändrad i version 3.3: Argumentet strict har tagits bort. Nyckelordet policy har lagts till.

email.message_from_string(s, _class=None, *, policy=policy.compat32)

Returnerar en meddelandeobjektstruktur från en sträng. Detta är likvärdigt med Parser().parsestr(s). _class och policy tolkas som med Parser-klassens konstruktör.

Ändrad i version 3.3: Argumentet strict har tagits bort. Nyckelordet policy har lagts till.

email.message_from_file(fp, _class=None, *, policy=policy.compat32)

Returnerar ett strukturträd för meddelandeobjekt från ett öppet filobjekt. Detta är likvärdigt med Parser().parse(fp). _class och policy tolkas som med Parser klasskonstruktören.

Ändrad i version 3.3: Argumentet strict har tagits bort. Nyckelordet policy har lagts till.

Ändrad i version 3.6: _class Standardvärdet är policyn message_factory.

Här är ett exempel på hur du kan använda message_from_bytes() i en interaktiv Python-prompt:

>>> import email
>>> msg = email.message_from_bytes(myBytes)

Ytterligare anmärkningar

Här följer några kommentarer om semantiken i parsningen:

  • De flesta meddelanden av typen multipart som inte är av typen multipart analyseras som ett enda meddelandeobjekt med en sträng som nyttolast. Dessa objekt kommer att returnera False för is_multipart(), och iter_parts() kommer att ge en tom lista.

  • Alla meddelanden av typen multipart tolkas som ett containermeddelandeobjekt med en lista över undermeddelandeobjekt för nyttolasten. Det yttre containermeddelandet returnerar True för is_multipart(), och iter_parts() ger en lista med underdelar.

  • De flesta meddelanden med innehållstypen message/* (t.ex. message/delivery-status och message/rfc822) kommer också att analyseras som containerobjekt som innehåller en list payload av längd 1. Deras metod is_multipart() kommer att returnera True. Det enskilda element som erhålls genom iter_parts() kommer att vara ett undermeddelandeobjekt.

  • Vissa meddelanden som inte följer standarderna kanske inte är internt konsekventa när det gäller deras multipart-edness. Sådana meddelanden kan ha en Content-Type header av typen multipart, men deras is_multipart() metod kan returnera False. Om sådana meddelanden analyserades med FeedParser, kommer de att ha en instans av MultipartInvariantViolationDefect-klassen i sin defects-attributlista. Se email.errors för detaljer.