Кажется вероятным, что по крайней мере некоторые из обрабатываемых вами электронных писем были закодированы как цитата-печатная .
Это кодирование используется для обеспечения переносимости 8-битных символьных данных по 7-битным (только для ASCII) системам, но также обеспечивает фиксированную длину строки в 76 символов.Это реализуется путем вставки мягкого разрыва строки, состоящего из «=», за которым следует маркер конца строки.
Python предоставляет модуль quopri для обработки кодирования и декодирования из цитируемой печати.Декодирование ваших данных из quoted-printable удалит эти мягкие разрывы строк.
В качестве примера, давайте использовать первый абзац вашего вопроса.
>>> import quopri
>>> s = """I'm writing a small script to run through large folders of copyright notice emails and finding relevant information (IP and timestamp). I've already found ways around a few little formatting hurdles (sometimes IP and TS are on different lines, sometimes on same, sometimes in different places, timestamps come in 4 different formats, etc.)."""
>>> # Encode to latin-1 as quopri deals with bytes, not strings.
>>> bs = s.encode('latin-1')
>>> # Encode
>>> encoded = quopri.encodestring(bs)
>>> # Observe the "=\n" inserted into the text.
>>> encoded
b"I'm writing a small script to run through large folders of copyright notice=\n emails and finding relevant information (IP and timestamp). I've already f=\nound ways around a few little formatting hurdles (sometimes IP and TS are o=\nn different lines, sometimes on same, sometimes in different places, timest=\namps come in 4 different formats, etc.)."
>>> # Printing without decoding from quoted-printable shows the "=".
>>> print(encoded.decode('latin-1'))
I'm writing a small script to run through large folders of copyright notice=
emails and finding relevant information (IP and timestamp). I've already f=
ound ways around a few little formatting hurdles (sometimes IP and TS are o=
n different lines, sometimes on same, sometimes in different places, timest=
amps come in 4 different formats, etc.).
>>> # Decode from quoted-printable to remove soft line breaks.
>>> print(quopri.decodestring(encoded).decode('latin-1'))
I'm writing a small script to run through large folders of copyright notice emails and finding relevant information (IP and timestamp). I've already found ways around a few little formatting hurdles (sometimes IP and TS are on different lines, sometimes on same, sometimes in different places, timestamps come in 4 different formats, etc.).
Чтобы правильно декодировать, все тело сообщениянеобходимо обработать, что противоречит вашему подходу с использованием readline
.Одним из способов решения этой проблемы является загрузка декодированной строки в буфер:
import io
def getIP(em):
with open(em, 'rb') as f:
bs = f.read()
decoded = quopri.decodestring(bs).decode('latin-1')
ce = io.StringIO(decoded)
iplabel = ""
while not ("Torrent Hash Value: " in iplabel):
iplabel = ce.readline()
...
Если ваши файлы содержат полные электронные письма, включая заголовки, то с помощью инструментов модуля email это можно будет обработать.декодирование автоматически.
import email
from email import policy
with open('message.eml') as f:
s = f.read()
msg = email.message_from_string(s, policy=policy.default)
body = msg.get_content()