Python imaplib yordamida pochta avtomatizatsiyasini o'rganing. IMAP serverlariga ulanish, xatlarni qidirish, olish, tahlil qilish va pochta qutisini professional darajada boshqarish.
Python IMAP Mijozi: Elektron Xatlarni Olish va Pochta Qutisini Boshqarish bo'yicha To'liq Qo'llanma
Elektron pochta butun dunyodagi biznes va jismoniy shaxslar uchun raqamli muloqotning asosiy toshi bo'lib qolmoqda. Biroq, katta hajmdagi elektron xatlarni boshqarish ko'p vaqt talab qiladigan va takrorlanuvchi vazifa bo'lishi mumkin. Hisob-fakturalarni qayta ishlash va bildirishnomalarni filtrlashdan tortib, muhim suhbatlarni arxivlashgacha, qo'lda bajariladigan ishlar tezda haddan tashqari ko'payib ketishi mumkin. Aynan shu yerda dasturiy avtomatlashtirish o'zini namoyon qiladi va Python o'zining boy standart kutubxonasi bilan pochta qutingizni nazorat qilish uchun kuchli vositalarni taqdim etadi.
Ushbu keng qamrovli qo'llanma sizga o'rnatilgan imaplib
kutubxonasidan foydalanib, noldan Python IMAP mijozini yaratish jarayonini bosqichma-bosqich ko'rsatib beradi. Siz nafaqat elektron xatlarni qanday olishni, balki ularning tarkibini tahlil qilishni, biriktirmalarni yuklab olishni va xabarlarni o'qilgan deb belgilash, ularni ko'chirish yoki o'chirish orqali pochta qutingizni boshqarishni o'rganasiz. Ushbu maqola oxiriga kelib, siz eng zerikarli elektron pochta vazifalarini avtomatlashtirishga tayyor bo'lasiz, bu esa vaqtingizni tejashga va unumdorligingizni oshirishga yordam beradi.
Protokollarni tushunish: IMAP, POP3 va SMTP
Kodga sho'ng'ishdan oldin, elektron pochtani boshqaradigan asosiy protokollarni tushunish muhimdir. Siz tez-tez uchta qisqartmani eshitasiz: SMTP, POP3 va IMAP. Ularning har biri o'ziga xos maqsadga xizmat qiladi.
- SMTP (Simple Mail Transfer Protocol): Bu elektron pochta yuborish uchun mo'ljallangan protokol. SMTP'ni sizning xatingizni olib, qabul qiluvchining pochta qutisi serveriga yetkazib beradigan pochta xizmati deb o'ylang. Python skriptingiz elektron pochta yuborganida, u SMTP'dan foydalanadi.
- POP3 (Post Office Protocol 3): Bu elektron pochta qabul qilish uchun mo'ljallangan protokol. POP3 serverga ulanish, barcha yangi xabarlarni mahalliy mijozingizga yuklab olish va keyin, sukut bo'yicha, ularni serverdan o'chirish uchun mo'ljallangan. Bu pochtaga borib, barcha xatlaringizni yig'ib, uyga olib ketishga o'xshaydi; ular uyingizga kelgandan so'ng, endi pochtada bo'lmaydi. Bu model bugungi kunda ko'p qurilmalar dunyosidagi cheklovlari tufayli kamroq tarqalgan.
- IMAP (Internet Message Access Protocol): Bu elektron pochtaga kirish va uni boshqarish uchun zamonaviy protokol. POP3'dan farqli o'laroq, IMAP xabarlarni serverda qoldiradi va holatni (o'qilgan, o'qilmagan, belgilangan, o'chirilgan) barcha ulangan mijozlar bo'ylab sinxronlashtiradi. Telefoningizda elektron xatni o'qiganingizda, u noutbukingizda ham o'qilgan bo'lib ko'rinadi. Ushbu serverga yo'naltirilgan model avtomatlashtirish uchun juda mos keladi, chunki sizning skriptingiz pochta qutisi bilan boshqa bir mijoz sifatida ishlashi mumkin va u kiritgan o'zgarishlar hamma joyda aks etadi. Ushbu qo'llanma uchun biz faqat IMAP'ga e'tibor qaratamiz.
Python'ning imaplib
kutubxonasi bilan ishlashni boshlash
Python'ning standart kutubxonasi IMAP serveri bilan aloqa qilish uchun barcha kerakli vositalarni taqdim etuvchi imaplib
modulini o'z ichiga oladi. Ishni boshlash uchun hech qanday tashqi paketlar talab qilinmaydi.
Boshlang'ich talablar
- Python o'rnatilganligi: Tizimingizda Python'ning so'nggi versiyasi (3.6 yoki undan yangiroq) o'rnatilganligiga ishonch hosil qiling.
- IMAP yoqilgan elektron pochta hisobi: Ko'pgina zamonaviy elektron pochta provayderlari (Gmail, Outlook, Yahoo va boshqalar) IMAP'ni qo'llab-quvvatlaydi. Siz uni hisobingiz sozlamalarida yoqishingiz kerak bo'lishi mumkin.
Avvalo xavfsizlik: Asosiy parolingizni emas, balki ilova parollaridan foydalaning
Bu xavfsizlik uchun eng muhim qadamdir. Asosiy elektron pochta hisobingiz parolini skriptingizga qattiq kodlab yozmang. Agar kodingiz buzilsa, butun hisobingiz xavf ostida qoladi. Ikki faktorli autentifikatsiyadan (2FA) foydalanadigan ko'pgina yirik pochta provayderlari sizdan "Ilova paroli" yaratishni talab qiladi.
Ilova paroli - bu ma'lum bir dasturga sizning asosiy parolingiz yoki 2FA kodlaringizsiz hisobingizga kirishga ruxsat beruvchi noyob, 16 xonali paroldir. Siz uni yaratishingiz va istalgan vaqtda asosiy parolingizga ta'sir qilmasdan bekor qilishingiz mumkin.
- Gmail uchun: Google hisobingiz sozlamalari -> Xavfsizlik -> 2 bosqichli tekshirish -> Ilovalar parollari ga o'ting.
- Outlook/Microsoft uchun: Microsoft hisobingiz xavfsizlik paneli -> Kengaytirilgan xavfsizlik parametrlari -> Ilova parollari ga o'ting.
- Boshqa provayderlar uchun: Ularning hujjatlaridan "ilova paroli" yoki "dasturga xos parol" deb qidiring.
Yaratilgandan so'ng, ushbu Ilova Paroliga boshqa har qanday hisob ma'lumoti kabi munosabatda bo'ling. Eng yaxshi amaliyot - uni manba kodingizda to'g'ridan-to'g'ri saqlash o'rniga muhit o'zgaruvchisida yoki xavfsiz maxfiy ma'lumotlarni boshqarish tizimida saqlashdir.
Asosiy ulanish
Keling, IMAP serveriga xavfsiz ulanishni o'rnatish, tizimga kirish va keyin to'g'ri chiqish uchun birinchi kod qismini yozamiz. Ulanishimiz shifrlanganligini ta'minlash uchun biz imaplib.IMAP4_SSL
dan foydalanamiz.
import imaplib
import os
# --- Hisob ma'lumotlari ---
# Bularni muhit o'zgaruvchilaridan yoki konfiguratsiya faylidan yuklash ma'qul
# Bu misol uchun ularni shu yerda aniqlaymiz. O'zingizning ma'lumotlaringiz bilan almashtiring.
EMAIL_ACCOUNT = "your_email@example.com"
APP_PASSWORD = "your_16_digit_app_password"
IMAP_SERVER = "imap.example.com" # masalan, "imap.gmail.com"
# --- IMAP serveriga ulanish ---
# Tizimdan to'g'ri chiqishni ta'minlash uchun try...finally blokidan foydalanamiz
conn = None
try:
# Xavfsiz ulanish uchun SSL yordamida ulanish
conn = imaplib.IMAP4_SSL(IMAP_SERVER)
# Hisobga kirish
status, messages = conn.login(EMAIL_ACCOUNT, APP_PASSWORD)
if status == 'OK':
print("Muvaffaqiyatli kirildi!")
# Bu yerga keyinroq ko'proq mantiq qo'shamiz
else:
print(f"Kirish muvaffaqiyatsiz: {messages}")
finally:
if conn:
# Har doim tizimdan chiqish va ulanishni yopish
conn.logout()
print("Tizimdan chiqildi va ulanish yopildi.")
Ushbu skript asos yaratadi. try...finally
bloki juda muhim, chunki u bizning operatsiyalarimiz davomida xatolik yuzaga kelgan taqdirda ham conn.logout()
chaqirilishini va server bilan sessiyani yopishini kafolatlaydi.
Pochta qutingizda harakatlanish
Tizimga kirgandan so'ng, hisobingizdagi pochta qutilari (ko'pincha papkalar deb ataladi) bilan ishlashni boshlashingiz mumkin.
Barcha pochta qutilarini ro'yxatlash
Qanday pochta qutilari mavjudligini ko'rish uchun conn.list()
usulidan foydalanishingiz mumkin. Chiqarilgan ma'lumot biroz tartibsiz bo'lishi mumkin, shuning uchun nomlarning toza ro'yxatini olish uchun biroz tahlil qilish kerak.
# Muvaffaqiyatli kirishdan so'ng 'try' bloki ichida:
status, mailbox_list = conn.list()
if status == 'OK':
print("Mavjud pochta qutilari:")
for mailbox in mailbox_list:
# Xom pochta qutisi yozuvi dekodlashni talab qiladigan bayt satridir
# U ko'pincha bunday formatda bo'ladi: (\HasNoChildren) "/" "INBOX"
# Uni tozalash uchun ba'zi asosiy tahlillarni amalga oshirishimiz mumkin
parts = mailbox.decode().split(' "/" ')
if len(parts) == 2:
mailbox_name = parts[1].strip('"')
print(f"- {mailbox_name}")
Bu sizning elektron pochta provayderingizga qarab 'INBOX', 'Sent', '[Gmail]/Spam' kabi ro'yxatni chiqaradi.
Pochta qutisini tanlash
Elektron xatlarni qidirish yoki olishdan oldin, ishlash uchun pochta qutisini tanlashingiz kerak. Eng keng tarqalgan tanlov - 'INBOX'. conn.select()
usuli pochta qutisini faol qiladi. Agar o'zgartirishlar kiritishni niyat qilmasangiz (masalan, elektron xatlarni o'qilgan deb belgilash), uni faqat o'qish rejimida ham ochishingiz mumkin.
# Ishlash uchun 'INBOX'ni tanlang.
# Xat belgilarini o'zgartirishni istamasangiz (masalan, UNSEEN'dan SEEN'ga), readonly=True dan foydalaning
status, messages = conn.select('INBOX', readonly=False)
if status == 'OK':
total_messages = int(messages[0])
print(f"INBOX tanlandi. Jami xabarlar: {total_messages}")
else:
print(f"INBOX tanlash muvaffaqiyatsiz: {messages}")
Pochta qutisini tanlaganingizda, server undagi xabarlarning umumiy sonini qaytaradi. Qidirish va olish uchun keyingi barcha buyruqlar ushbu tanlangan pochta qutisiga nisbatan qo'llaniladi.
Elektron xatlarni qidirish va olish
Bu elektron xatlarni olishning asosiy qismidir. Jarayon ikki bosqichdan iborat: birinchidan, ma'lum mezonlarga mos keladigan xabarlarni ularning noyob ID'larini olish uchun qidirish, ikkinchidan, ushbu ID'lardan foydalanib o'sha xabarlarning mazmunini olish.
search()
ning kuchi
search()
usuli juda ko'p qirrali. U elektron xatlarning o'zini emas, balki so'rovingizga mos keladigan xabar ketma-ketlik raqamlari (ID) ro'yxatini qaytaradi. Bu ID'lar joriy sessiya va tanlangan pochta qutisiga xosdir.
Quyida eng keng tarqalgan qidiruv mezonlari keltirilgan:
'ALL'
: Pochta qutisidagi barcha xabarlar.'UNSEEN'
: Hali o'qilmagan xabarlar.'SEEN'
: O'qilgan xabarlar.'FROM "sender@example.com"'
: Muayyan yuboruvchidan kelgan xabarlar.'TO "recipient@example.com"'
: Muayyan qabul qiluvchiga yuborilgan xabarlar.'SUBJECT "Your Subject Line"'
: Muayyan mavzudagi xabarlar.'BODY "a keyword in the body"'
: Matnida ma'lum bir satrni o'z ichiga olgan xabarlar.'SINCE "01-Jan-2024"'
: Muayyan sanada yoki undan keyin qabul qilingan xabarlar.'BEFORE "31-Jan-2024"'
: Muayyan sanadan oldin qabul qilingan xabarlar.
Siz mezonlarni birlashtirishingiz ham mumkin. Masalan, ma'lum bir yuboruvchidan kelgan barcha o'qilmagan elektron xatlarni ma'lum bir mavzu bilan topish uchun siz '(UNSEEN FROM "alerts@example.com" SUBJECT "System Alert")'
deb qidirasiz.
Keling, buni amalda ko'rib chiqamiz:
# INBOX'dagi barcha o'qilmagan elektron xatlarni qidirish
status, message_ids = conn.search(None, 'UNSEEN')
if status == 'OK':
# message_ids - bayt satrlari ro'yxati, masalan, [b'1 2 3']
# Biz uni alohida ID'larga ajratishimiz kerak
email_id_list = message_ids[0].split()
if email_id_list:
print(f"{len(email_id_list)} ta o'qilmagan xat topildi.")
else:
print("O'qilmagan xatlar topilmadi.")
else:
print("Qidiruv muvaffaqiyatsiz tugadi.")
fetch()
yordamida elektron xat mazmunini olish
Endi sizda xabar ID'lari bor, siz fetch()
usulidan foydalanib, haqiqiy elektron pochta ma'lumotlarini olishingiz mumkin. Siz elektron pochtaning qaysi qismlarini xohlayotganingizni ko'rsatishingiz kerak.
'RFC822'
: Bu barcha sarlavhalar va matn qismlarini o'z ichiga olgan butun xom elektron pochta mazmunini oladi. Bu eng keng tarqalgan va keng qamrovli variant.'BODY[]'
: `RFC822` uchun sinonim.'ENVELOPE'
: Sana, Mavzu, Kimdan, Kimga va Javoban kabi asosiy sarlavha ma'lumotlarini oladi. Agar sizga faqat metama'lumotlar kerak bo'lsa, bu tezroq.'BODY[HEADER]'
: Faqat sarlavhalarni oladi.
Keling, topgan birinchi o'qilmagan elektron xatimizning to'liq mazmunini olamiz:
if email_id_list:
first_email_id = email_id_list[0]
# Berilgan ID uchun elektron pochta ma'lumotlarini olish
# 'RFC822' - matnli xabarlar formatini belgilaydigan standart
status, msg_data = conn.fetch(first_email_id, '(RFC822)')
if status == 'OK':
for response_part in msg_data:
# fetch buyrug'i kortej qaytaradi, uning ikkinchi qismi elektron pochta mazmuni
if isinstance(response_part, tuple):
raw_email = response_part[1]
# Endi bizda xom elektron pochta ma'lumotlari baytlar sifatida mavjud
# Keyingi qadam uni tahlil qilishdir
print("Elektron xat muvaffaqiyatli olindi.")
# `raw_email`ni keyingi bo'limda qayta ishlaymiz
else:
print("Olish muvaffaqiyatsiz tugadi.")
Elektron pochta mazmunini email
moduli bilan tahlil qilish
fetch()
tomonidan qaytarilgan xom ma'lumotlar RFC 822 standartiga muvofiq formatlangan bayt satridir. Uni o'qish oson emas. Python'ning o'rnatilgan email
moduli aynan shu xom xabarlarni foydalanuvchiga qulay obyekt tuzilmasiga tahlil qilish uchun mo'ljallangan.
Message
obyektini yaratish
Birinchi qadam xom bayt satrini `email.message_from_bytes()` yordamida Message
obyektiga aylantirishdir.
import email
from email.header import decode_header
# `raw_email` fetch buyrug'idan olingan bayt ma'lumotlarini o'z ichiga oladi deb faraz qilamiz
email_message = email.message_from_bytes(raw_email)
Asosiy ma'lumotlarni (sarlavhalarni) ajratib olish
Message
obyektiga ega bo'lgandan so'ng, uning sarlavhalariga lug'at kabi kirishingiz mumkin.
# Mavzu, kimdan, kimga va sanani olish
subject = email_message["Subject"]
from_ = email_message["From"]
to_ = email_message["To"]
date_ = email_message["Date"]
# Elektron pochta sarlavhalari ASCII bo'lmagan belgilarni o'z ichiga olishi mumkin, shuning uchun ularni dekodlashimiz kerak
def decode_email_header(header):
decoded_parts = decode_header(header)
header_str = ""
for part, encoding in decoded_parts:
if isinstance(part, bytes):
# Agar kodlash mavjud bo'lsa, undan foydalaning. Aks holda, sukut bo'yicha utf-8.
header_str += part.decode(encoding or 'utf-8')
else:
header_str += part
return header_str
subject = decode_email_header(subject)
from_ = decode_email_header(from_)
print(f"Mavzu: {subject}")
print(f"Kimdan: {from_}")
decode_email_header
yordamchi funksiyasi muhim, chunki sarlavhalar ko'pincha xalqaro belgi to'plamlarini qo'llab-quvvatlash uchun kodlanadi. Agar siz uni to'g'ri dekodlamasangiz, shunchaki email_message["Subject"]
ga murojaat qilish sizga chalkash belgi ketma-ketliklari bo'lgan satrni berishi mumkin.
Elektron pochta matnlari va biriktirmalarni boshqarish
Zamonaviy elektron xatlar ko'pincha "ko'p qismli" bo'ladi, ya'ni ular tarkibning turli versiyalarini (oddiy matn va HTML kabi) o'z ichiga oladi va shuningdek biriktirmalarga ega bo'lishi mumkin. Biz qidirayotgan narsani topish uchun ushbu qismlarni ko'rib chiqishimiz kerak.
msg.is_multipart()
usuli bizga elektron pochtaning bir nechta qismi bor-yo'qligini aytadi va msg.walk()
ular bo'ylab osonlikcha iteratsiya qilish imkonini beradi.
def process_email_body(msg):
body = ""
attachments = []
if msg.is_multipart():
# Elektron pochta qismlari bo'ylab iteratsiya qilish
for part in msg.walk():
content_type = part.get_content_type()
content_disposition = str(part.get("Content-Disposition"))
try:
# Elektron pochta matnini olish
if content_type == "text/plain" and "attachment" not in content_disposition:
payload = part.get_payload(decode=True)
charset = part.get_content_charset() or 'utf-8'
body = payload.decode(charset)
# Biriktirmalarni olish
elif "attachment" in content_disposition:
filename = part.get_filename()
if filename:
# Agar kerak bo'lsa, fayl nomini dekodlash
decoded_filename = decode_email_header(filename)
attachments.append({
'filename': decoded_filename,
'data': part.get_payload(decode=True)
})
except Exception as e:
print(f"Qismni qayta ishlashda xatolik: {e}")
else:
# Ko'p qismli xabar emas, shunchaki yukni olish
payload = msg.get_payload(decode=True)
charset = msg.get_content_charset() or 'utf-8'
body = payload.decode(charset)
return body, attachments
# Funksiyani olingan xabarimiz bilan ishlatish
email_body, email_attachments = process_email_body(email_message)
print("\n--- Elektron Pochta Matni ---")
print(email_body)
if email_attachments:
print("\n--- Biriktirmalar ---")
for att in email_attachments:
print(f"Fayl nomi: {att['filename']}")
# Biriktirmani saqlash misoli
with open(att['filename'], 'wb') as f:
f.write(att['data'])
print(f"Biriktirma saqlandi: {att['filename']}")
Bu funksiya har bir qismning Content-Type
va Content-Disposition
sarlavhalarini tekshirish orqali oddiy matn va fayl biriktirmalari o'rtasidagi farqni aqlli ravishda aniqlaydi.
Pochta qutisini ilg'or boshqarish
Elektron xatlarni olish jangning faqat yarmi. Haqiqiy avtomatlashtirish serverdagi xabarlarning holatini o'zgartirishni o'z ichiga oladi. store()
buyrug'i buning uchun sizning asosiy vositangizdir.
Elektron xatlarni belgilash (O'qilgan, O'qilmagan, Belgilangan)
Siz xabarga belgilar qo'shishingiz, olib tashlashingiz yoki almashtirishingiz mumkin. Eng keng tarqalgan belgi \Seen
bo'lib, u o'qilgan/o'qilmagan holatini nazorat qiladi.
- O'qilgan deb belgilash:
conn.store(msg_id, '+FLAGS', '\Seen')
- O'qilmagan deb belgilash:
conn.store(msg_id, '-FLAGS', '\Seen')
- Xatni belgilash/yulduzcha qo'yish:
conn.store(msg_id, '+FLAGS', '\Flagged')
- Xat belgisini olib tashlash:
conn.store(msg_id, '-FLAGS', '\Flagged')
Elektron xatlarni nusxalash va ko'chirish
IMAP'da to'g'ridan-to'g'ri "ko'chirish" buyrug'i mavjud emas. Elektron xatni ko'chirish ikki bosqichli jarayondir:
- Xabarni
conn.copy()
yordamida belgilangan pochta qutisiga nusxalash. - Asl xabarni
\Deleted
belgisidan foydalanib o'chirish uchun belgilash.
# `msg_id` ko'chiriladigan xatning ID'si deb faraz qilamiz
# 1. 'Archive' pochta qutisiga nusxalash
status, _ = conn.copy(msg_id, 'Archive')
if status == 'OK':
print(f"{msg_id.decode()} xabari Arxivga nusxalandi.")
# 2. Aslini o'chirish uchun belgilash
conn.store(msg_id, '+FLAGS', '\Deleted')
print(f"{msg_id.decode()} xabari o'chirish uchun belgilandi.")
Elektron xatlarni butunlay o'chirish
Xabarni \Deleted
bilan belgilash uni darhol o'chirmaydi. Bu uni ko'pchilik elektron pochta mijozlarida shunchaki ko'rinmas qilib qo'yadi. Joriy tanlangan pochta qutisidagi o'chirish uchun belgilangan barcha xabarlarni butunlay o'chirish uchun siz expunge()
usulini chaqirishingiz kerak.
Ogohlantirish: expunge()
qaytarib bo'lmaydigan amaldir. U chaqirilgandan so'ng, ma'lumotlar butunlay yo'qoladi.
# Bu \Deleted belgisi bo'lgan barcha xabarlarni butunlay o'chiradi
status, response = conn.expunge()
if status == 'OK':
print(f"{len(response)} ta xabar tozalandi (butunlay o'chirildi).")
expunge()
ning muhim yon ta'siri shundaki, u pochta qutisidagi keyingi barcha xabarlar uchun xabar ID'larini qayta raqamlashi mumkin. Shu sababli, qayta ishlamoqchi bo'lgan barcha xabarlarni aniqlab, amallarni (nusxalash va o'chirish uchun belgilash kabi) bajarib, so'ngra sessiyangizning eng oxirida bir marta expunge()
ni chaqirish eng yaxshisidir.
Barchasini birlashtirish: Amaliy misol
Keling, haqiqiy dunyo vazifasini bajaradigan to'liq skript yaratamiz: Kirish qutisini "invoices@mycorp.com" dan kelgan o'qilmagan elektron xatlar uchun skanerlash, har qanday PDF biriktirmalarni yuklab olish va qayta ishlangan elektron xatni "Processed-Invoices" nomli pochta qutisiga ko'chirish.
import imaplib
import email
from email.header import decode_header
import os
# --- Konfiguratsiya ---
EMAIL_ACCOUNT = "your_email@example.com"
APP_PASSWORD = "your_16_digit_app_password"
IMAP_SERVER = "imap.gmail.com"
TARGET_SENDER = "invoices@mycorp.com"
DESTINATION_MAILBOX = "Processed-Invoices"
DOWNLOAD_DIR = "invoices"
# Agar yuklab olish katalogi mavjud bo'lmasa, uni yaratish
if not os.path.isdir(DOWNLOAD_DIR):
os.mkdir(DOWNLOAD_DIR)
def decode_email_header(header):
# (Avvalroq aniqlangan funksiya bilan bir xil)
decoded_parts = decode_header(header)
header_str = ""
for part, encoding in decoded_parts:
if isinstance(part, bytes):
header_str += part.decode(encoding or 'utf-8')
else:
header_str += part
return header_str
conn = None
try:
# --- Ulanish va Tizimga kirish ---
conn = imaplib.IMAP4_SSL(IMAP_SERVER)
conn.login(EMAIL_ACCOUNT, APP_PASSWORD)
print("Tizimga kirish muvaffaqiyatli.")
# --- INBOX'ni tanlash ---
conn.select('INBOX')
print("INBOX tanlandi.")
# --- Elektron xatlarni qidirish ---
search_criteria = f'(UNSEEN FROM "{TARGET_SENDER}")'
status, message_ids = conn.search(None, search_criteria)
if status != 'OK':
raise Exception("Qidiruv muvaffaqiyatsiz tugadi")
email_id_list = message_ids[0].split()
if not email_id_list:
print("Yangi hisob-fakturalar topilmadi.")
else:
print(f"{len(email_id_list)} ta yangi hisob-faktura qayta ishlash uchun topildi.")
# --- Har bir elektron xatni qayta ishlash ---
for email_id in email_id_list:
print(f"\nElektron xat ID'si qayta ishlanmoqda: {email_id.decode()}")
# Elektron xatni olish
status, msg_data = conn.fetch(email_id, '(RFC822)')
if status != 'OK':
print(f"Elektron xat ID {email_id.decode()} ni olish muvaffaqiyatsiz tugadi")
continue
raw_email = msg_data[0][1]
email_message = email.message_from_bytes(raw_email)
subject = decode_email_header(email_message["Subject"])
print(f" Mavzu: {subject}")
# Biriktirmalarni qidirish
for part in email_message.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if filename and filename.lower().endswith('.pdf'):
decoded_filename = decode_email_header(filename)
filepath = os.path.join(DOWNLOAD_DIR, decoded_filename)
# Biriktirmani saqlash
with open(filepath, 'wb') as f:
f.write(part.get_payload(decode=True))
print(f" -> Yuklab olingan biriktirma: {decoded_filename}")
# --- Qayta ishlangan elektron xatni ko'chirish ---
# 1. Belgilangan pochta qutisiga nusxalash
status, _ = conn.copy(email_id, DESTINATION_MAILBOX)
if status == 'OK':
# 2. Aslini o'chirish uchun belgilash
conn.store(email_id, '+FLAGS', '\Deleted')
print(f" Elektron xat '{DESTINATION_MAILBOX}' ga ko'chirildi.")
# --- Tozalash va Tartibga solish ---
if email_id_list:
conn.expunge()
print("\nO'chirilgan elektron xatlar tozalandi.")
except Exception as e:
print(f"Xatolik yuz berdi: {e}")
finally:
if conn:
conn.logout()
print("Tizimdan chiqildi.")
Eng yaxshi amaliyotlar va xatoliklarni boshqarish
Ishonchli avtomatlashtirish skriptlarini yaratishda quyidagi eng yaxshi amaliyotlarni ko'rib chiqing:
- Mustahkam xatoliklarni boshqarish: Tizimga kirishdagi nosozliklar (
imaplib.IMAP4.error
), tarmoq muammolari yoki tahlil qilish xatolari kabi potentsial muammolarni ushlash uchun kodingiznitry...except
bloklariga o'rang. - Konfiguratsiyani boshqarish: Hech qachon hisob ma'lumotlarini qattiq kodlab yozmang. Muhit o'zgaruvchilaridan (
os.getenv()
), konfiguratsiya faylidan (masalan, INI yoki YAML) yoki maxsus maxfiy ma'lumotlar menejeridan foydalaning. - Jurnalga yozish (Logging):
print()
bayonotlari o'rniga Python'ninglogging
modulidan foydalaning. Bu sizga chiqish ma'lumotlarining batafsilligini nazorat qilish, fayllarga yozish va vaqt belgilarini qo'shish imkonini beradi, bu esa qarovsiz ishlaydigan skriptlarni tuzatish uchun bebahodir. - So'rovlarni cheklash (Rate Limiting): Yaxshi internet fuqarosi bo'ling. Elektron pochta serveriga haddan tashqari ko'p so'rov yubormang. Agar siz yangi pochtani tez-tez tekshirishingiz kerak bo'lsa, soniyalar o'rniga bir necha daqiqalik intervallarni ko'rib chiqing.
- Belgi kodlashlari: Elektron pochta global standartdir va siz turli xil belgi kodlashlariga duch kelasiz. Har doim belgi to'plamini elektron pochta qismidan (
part.get_content_charset()
) aniqlashga harakat qiling va `UnicodeDecodeError` dan qochish uchun zaxira variantiga (masalan, 'utf-8') ega bo'ling.
Xulosa
Siz endi Python'ning imaplib
kutubxonasidan foydalanib, elektron pochta serveri bilan ishlashning butun hayotiy siklidan o'tdingiz. Biz xavfsiz ulanishni o'rnatish, pochta qutilarini ro'yxatlash, kuchli qidiruvlarni amalga oshirish, murakkab ko'p qismli elektron xatlarni olish va tahlil qilish, biriktirmalarni yuklab olish va serverdagi xabar holatlarini boshqarishni ko'rib chiqdik.
Ushbu bilimlarning kuchi juda katta. Siz qo'llab-quvvatlash chiptalarini avtomatik ravishda tasniflash, kunlik hisobotlardan ma'lumotlarni tahlil qilish, yangiliklar xabarnomalarini arxivlash, ogohlantirish elektron xatlari asosida harakatlarni ishga tushirish va boshqa ko'p narsalar uchun tizimlar yaratishingiz mumkin. Bir paytlar qo'l mehnati manbai bo'lgan kirish qutisi sizning ilovalaringiz va ish oqimlaringiz uchun kuchli, avtomatlashtirilgan ma'lumotlar manbaiga aylanishi mumkin.
Siz birinchi navbatda qaysi elektron pochta vazifalarini avtomatlashtirasiz? Imkoniyatlar faqat sizning tasavvuringiz bilan cheklangan. Kichikdan boshlang, ushbu qo'llanmadagi misollarga asoslaning va vaqtingizni pochta qutingiz chuqurliklaridan qaytarib oling.