2.4 KiB
2.4 KiB
PDF Attachment Extraction from Multipart/Mixed Emails
Airline ticket receipts (Copa, American, United, Delta) often embed PDF attachments inside multipart/mixed MIME messages alongside inline images (logos, QR codes).
Key pattern
The PDF is typically the last meaningful attachment in the MIME tree, surrounded by 6-8 image/jpeg inline images. Don't assume the first .pdf match is the right one — iterate all parts and pick the one with the correct filename.
for part in raw.walk():
fn = part.get_filename()
if fn and fn.endswith('.pdf'):
payload = part.get_payload(decode=True)
# Save to disk
with open("/tmp/ticket.pdf", 'wb') as f:
f.write(payload)
# Or parse directly from memory
from pdfminer.high_level import extract_text
from io import BytesIO
text = extract_text(BytesIO(payload))
Parsing e-ticket PDFs with pdfminer
Install: pip3 install pdfminer.six
from pdfminer.high_level import extract_text
from io import BytesIO
text = extract_text(BytesIO(pdf_bytes))
# Extract flight numbers (Copa uses CM###)
for line in text.split('\n'):
if 'Flight Number' in line or 'CM ' in line:
flights.append(line.strip())
Common airline PDF fields
| Airline | Flight prefix | Confirmation length | PDF attachment name |
|---|---|---|---|
| Copa | CM | 6 alphanumeric (A4GSFD) | ETKT_*.pdf |
| American | AA | 6 alphanumeric | e-ticket-*.pdf |
| United | UA | 6 alphanumeric | itinerary-*.pdf |
| Delta | DL | 6 alphanumeric | eTicket*.pdf |
Pitfalls
- Copa tickets have 6-8 inline image parts (logo, QR, barcode, social icons) before the PDF. The PDF is typically the second-to-last or last attachment.
get_content_charset()may return None on PDFs — useutf-8oriso-8859-1fallback for the PDF parsing step (the PDF itself is binary, the charset applies to the text portion of the email, not the attachment).- Copa confirmation codes look like A4GSFD — 6 chars, alphanumeric. Found in the email subject line and the PDF body. Also stored in the email's
X-Confirmationheader (if present). - Header-only fetch (
BODY.PEEK[HEADER.FIELDS]) won't show attachment filenames. You need to fetch the full message body to find PDFs. - Some airlines use
Content-Type: application/octet-streaminstead ofapplication/pdffor PDF attachments. Checkget_filename()regardless of content type.