# `email.parser`: 전자 메일 메시지 구문 분석

소스 코드: Lib/email/parser.py

메시지 객체 구조는 두 가지 방법으로 만들 수 있습니다: `EmailMessage` 객체를 만들고, 딕셔너리 인터페이스를 사용하여 헤더를 추가하고, `set_content()`와 관련 메서드를 사용하여 페이 로드를 추가하여 아예 새로 만들 수 있습니다. 또는 전자 메일 메시지의 직렬화된 표현을 구문 분석해서 만들 수 있습니다.

`email` 패키지는 MIME 문서를 포함한 대부분의 전자 우편 문서 구조를 이해하는 표준 구문 분석기를 제공합니다. 구문 분석기에 바이트열, 문자열 또는 파일 객체를 전달하면 구문 분석기가 객체 구조의 루트 `EmailMessage` 인스턴스를 반환합니다. MIME이 아닌 간단한 메시지의 경우 이 루트 객체의 페이 로드는 메시지의 텍스트를 포함하는 문자열일 수 있습니다. MIME 메시지의 경우 루트 객체는 `is_multipart()` 메서드가 `True`를 반환하고, `get_body()`, `iter_parts()` 및 `walk()`와 같은 페이 로드 조작 메서드를 통해 서브 파트에 액세스 할 수 있습니다.

실제로 사용 가능한 두 가지 구문 분석기 인터페이스가 있습니다, `Parser` API와 증분 `FeedParser` API. `Parser` API는 메시지의 전체 텍스트가 메모리에 있거나 전체 메시지가 파일 시스템의 파일에 있을 때 가장 유용합니다. 더 많은 입력을 기다리기 위해 블록할 수 있는 스트림에서 메시지를 읽을 때는 `FeedParser`가 더 적합합니다 (가령 소켓에서 전자 메일 메시지를 읽을 때). `FeedParser`는 메시지를 증분 적으로 소비하고 구문 분석 할 수 있으며, 구문 분석기를 닫을 때만 루트 객체를 반환합니다.

Note that the parser can be extended in limited ways, and of course you can implement your own parser completely from scratch. All of the logic that connects the `email` package’s bundled parser and the `EmailMessage` class is embodied in the `Policy` class, so a custom parser can create message object trees any way it finds necessary by implementing custom versions of the appropriate `Policy` methods.

## FeedParser API

`email.feedparser` 모듈에서 임포트 한 `BytesFeedParser`는 전자 메일 메시지의 증분 구문 분석에 도움이 되는 API를 제공합니다. 블록할 수 있는 소스(가령 소켓)에서 전자 메일 메시지의 텍스트를 읽을 때 필요합니다. 물론 `BytesFeedParser`는 바이트열류 객체, 문자열 또는 파일에 완전히 포함된 전자 메일 메시지를 구문 분석하는 데 사용될 수 있지만, `BytesParser` API가 이러한 사용 사례에서는 더 편리 할 수 있습니다. 두 구문 분석기 API의 의미와 결과는 같습니다.

`BytesFeedParser`의 API는 간단합니다; 인스턴스를 만들고, 더는 공급할 것이 없을 때까지 바이트열을 공급한 다음 구문 분석기를 닫아 루트 메시지 객체를 얻습니다. `BytesFeedParser`는 표준 호환 메시지를 구문 분석할 때 매우 정확하고, 미준수 메시지를 구문 분석하는 데 매우 효과적이며 메시지를 어떻게 손상되었다고 간주하는지에 대한 정보를 제공합니다. 메시지에서 발견된 문제점 리스트로 메시지 객체의 `defects` 어트리뷰트를 채웁니다. 찾을 수 있는 결함 목록은 `email.errors` 모듈을 참조하십시오.

`BytesFeedParser` API는 다음과 같습니다:

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

  `BytesFeedParser` 인스턴스를 만듭니다. 선택적 _factory는 인자 없는 콜러블입니다; 지정되지 않으면 policy의 `message_factory`를 사용합니다. 새로운 메시지 객체가 필요할 때마다 _factory를 호출합니다.

  policy가 지정되면, 그것이 지정하는 규칙을 사용하여 메시지 표시를 갱신합니다. policy가 설정되지 않으면, `compat32` 정책을 사용합니다. 이 정책은 파이썬 3.2 버전의 email 패키지와의 호환성을 유지하고 `Message`를 기본 팩토리로 제공합니다. 다른 모든 정책은 `EmailMessage`를 기본 _factory로 제공합니다. policy가 제어하는 다른 기능에 대한 자세한 내용은 `policy` 설명서를 참조하십시오.

  참고: policy 키워드는 항상 지정해야 합니다; 이후 버전의 파이썬에서는 기본값이 `email.policy.default`로 변경됩니다.

  버전 3.2에 추가.

  버전 3.3에서 변경: policy 키워드를 추가했습니다.

  버전 3.6에서 변경: _factory는 기본적으로 정책 `message_factory`입니다.

  feed(data)

    구문 분석기에 데이터를 더 공급합니다. data는 하나 이상의 줄을 포함하는 바이트열류 객체여야 합니다. 줄은 부분적일 수 있고 구문 분석기는 그러한 부분적인 줄을 올바르게 이어붙입니다. 줄은 세 가지 일반 줄 종료 중 어느 것이라도 될 수 있습니다: 캐리지 리턴(carriage return), 줄 바꿈(newline) 또는 캐리지 리턴과 줄 바꿈 (이것들을 혼합할 수도 있습니다).

  close()

    이전에 제공된 모든 데이터의 구문 분석을 완료하고 루트 메시지 객체를 반환합니다. 이 메서드가 호출된 후 `feed()`가 호출되면 어떻게 되는지는 정의되지 않습니다.

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

  `feed()` 메서드에 대한 입력이 문자열이어야 한다는 점을 제외하고는 `BytesFeedParser`와 같게 작동합니다. 이러한 메시지가 유효할 수 있는 유일한 방법은 ASCII 텍스트만 포함하거나 `utf8`가 `True`일 때 바이너리 첨부 파일을 포함하지 않는 것이라서, 이것의 용도는 제한적입니다.

  버전 3.3에서 변경: policy 키워드를 추가했습니다.

## Parser API

`email.parser` 모듈에서 임포트 한 `BytesParser` 클래스는 메시지의 전체 내용이 바이트열류 객체나 파일로 있을 때 메시지를 구문 분석하는 데 사용할 수 있는 API를 제공합니다. `email.parser` 모듈은 또한 문자열 구문 분석을 위한 `Parser`와 메시지 헤더에만 관심이 있을 때 사용할 수 있는 헤더 전용 구문 분석기인 `BytesHeaderParser`와 `HeaderParser`를 제공합니다. `BytesHeaderParser`와 `HeaderParser`는 메시지 본문을 구문 분석하지 않고 페이 로드를 원시 본문으로 설정하기 때문에 이러한 상황에서 훨씬 더 빠를 수 있습니다.

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

  `BytesParser` 인스턴스를 만듭니다. _class와 policy 인자는 `BytesFeedParser` 의 _factory와 policy 인자와 같은 의미입니다.

  참고: policy 키워드는 항상 지정해야 합니다; 이후 버전의 파이썬에서는 기본값이 `email.policy.default`로 변경됩니다.

  버전 3.3에서 변경: 2.4에서 폐지된 strict 인자를 제거했습니다. policy 키워드를 추가했습니다.

  버전 3.6에서 변경: _class는 기본적으로 정책 `message_factory`입니다.

  parse(fp, headersonly=False)

    바이너리 파일류 객체 fp에서 모든 데이터를 읽고, 결과 바이트열을 구문 분석한 후, 메시지 객체를 반환합니다. fp는 `readline()`과 `read()` 메서드를 모두 지원해야 합니다.

    fp에 포함된 바이트열은 RFC 5322(또는 `utf8`가 `True`이면, RFC 6532) 블록 스타일 헤더와 헤더 연장 줄들로 포맷되어야 하며, 선택적으로 봉투 헤더가 앞에 올 수 있습니다. 헤더 블록은 데이터 끝이나 빈 줄로 종료됩니다. 헤더 블록 다음에는 메시지 본문이 있습니다 (Content-Transfer-Encoding이 `8bit`인 서브 파트를 포함하여 MIME 인코딩된 서브 파트를 포함할 수 있습니다).

    선택적 headersonly는 헤더를 읽은 후에 구문 분석을 중지할지를 지정하는 플래그입니다. 기본값은 `False`이며 파일의 전체 내용을 구문 분석합니다.

  parsebytes(bytes, headersonly=False)

    파일류 객체 대신 바이트열류 객체를 취한다는 점을 제외하고는 `parse()` 메서드와 유사합니다. 바이트열류 객체로 이 메서드를 호출하는 것은 `BytesIO` 인스턴스로 bytes를 먼저 감싸고 `parse()`를 호출하는 것과 동등합니다.

    선택적 headersonly는 `parse()` 메서드와 같습니다.

  버전 3.2에 추가.

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

  headersonly의 기본값이 `True`라는 점을 제외하고는 `BytesParser`와 정확히 같습니다.

  버전 3.3에 추가.

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

  이 클래스는 `BytesParser`와 유사하지만, 문자열 입력을 처리합니다.

  버전 3.3에서 변경: strict 인자를 제거했습니다. policy 키워드를 추가했습니다.

  버전 3.6에서 변경: _class는 기본적으로 정책 `message_factory`입니다.

  parse(fp, headersonly=False)

    텍스트 모드 파일류 객체 fp에서 모든 데이터를 읽고, 결과 텍스트를 구문 분석한 후, 루트 메시지 객체를 반환합니다. fp는 파일류 객체의 `readline()`과 `read()` 메서드를 모두 지원해야 합니다.

    텍스트 모드 요구 사항 외에, 이 메서드는 `BytesParser.parse()`처럼 작동합니다.

  parsestr(text, headersonly=False)

    파일류 객체 대신 문자열 객체를 취한다는 점을 제외하고는 `parse()` 메서드와 유사합니다. 문자열로 이 메서드를 호출하는 것은 `StringIO` 인스턴스로 text를 먼저 감싸고 `parse()`를 호출하는 것과 동등합니다.

    선택적 headersonly는 `parse()` 메서드와 같습니다.

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

  headersonly의 기본값이 `True`라는 점을 제외하고는 `Parser`와 정확히 같습니다.

문자열이나 파일 객체로부터 메시지 객체 구조를 만드는 것이 일반적인 작업이기 때문에, 편의상 4가지 함수가 제공됩니다. 최상위 `email` 패키지 이름 공간에 있습니다.

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

  바이트열류 객체로부터 메시지 객체 구조를 반환합니다. 이것은 `BytesParser().parsebytes(s)`와 동등합니다. 선택적 _class와 policy는 `BytesParser` 클래스 생성자에서처럼 해석됩니다.

  버전 3.2에 추가.

  버전 3.3에서 변경: strict 인자를 제거했습니다. policy 키워드를 추가했습니다.

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

  열린 바이너리 파일 객체로부터 메시지 객체 구조 트리를 반환합니다. 이것은 `BytesParser().parse(fp)`와 동등합니다. _class와 policy는 `BytesParser` 클래스 생성자에서처럼 해석됩니다.

  버전 3.2에 추가.

  버전 3.3에서 변경: strict 인자를 제거했습니다. policy 키워드를 추가했습니다.

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

  문자열로부터 메시지 객체 구조 트리를 반환합니다. 이것은 `Parser().parsestr(s)`와 동등합니다. _class와 policy는 `Parser` 클래스 생성자에서처럼 해석됩니다.

  버전 3.3에서 변경: strict 인자를 제거했습니다. policy 키워드를 추가했습니다.

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

  열린 파일 객체로부터 메시지 객체 구조 트리를 반환합니다. 이것은 `Parser().parse(fp)`와 동등합니다. _class와 policy는 `Parser` 클래스 생성자에서처럼 해석됩니다.

  버전 3.3에서 변경: strict 인자를 제거했습니다. policy 키워드를 추가했습니다.

  버전 3.6에서 변경: _class는 기본적으로 정책 `message_factory`입니다.

대화식 파이썬 프롬프트에서 `message_from_bytes()`를 사용하는 방법의 예는 다음과 같습니다:

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

## 추가 사항

구문 분석 의미에 대한 참고 사항은 다음과 같습니다:

- 대부분의 multipart가 아닌 유형의 메시지는 문자열 페이 로드가 있는 단일 메시지 객체로 구문 분석됩니다. 이 객체는 `is_multipart()`가 `False`를 반환하고 `iter_parts()`는 빈 목록을 산출합니다.

- 모든 multipart 유형 메시지는 서브 메시지 객체 리스트 페이 로드가 있는 컨테이너 메시지 객체로 구문 분석됩니다. 바깥 컨테이너 메시지는 `is_multipart()`가 `True`를 반환하고 `iter_parts()`는 서브 파트 목록을 산출합니다.

- 콘텐츠 유형이 message/*(가령 message/delivery-status와 message/rfc822)인 대부분의 메시지는 길이가 1인 리스트 페이 로드를 포함하는 컨테이너 객체로 구문 분석됩니다. `is_multipart()` 메서드는 `True`를 반환합니다. `iter_parts()`가 산출하는 단일 요소가 서브 메시지 객체입니다.

- 일부 표준을 준수하지 않는 메시지는 multipart 처리에 대해 내부적으로 일관성이 없을 수 있습니다. 이러한 메시지는 multipart 유형의 Content-Type 헤더를 가지면서도 `is_multipart()` 메서드가 `False`를 반환할 수 있습니다. 이러한 메시지가 `FeedParser`로 구문 분석되었다면, defects 어트리뷰트 리스트에 `MultipartInvariantViolationDefect` 클래스의 인스턴스가 있습니다. 자세한 내용은 `email.errors`를 참조하십시오.