Files
test_mail/main.py
2025-10-01 10:30:11 +05:00

329 lines
13 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import docx
import csv
import re
def extract_quoted_text(text):
"""Извлекает текст в кавычках «»"""
if not text:
return ""
match = re.search(r'«([^»]+)»', text)
return match.group(1).strip() if match else text.strip()
def extract_address(text):
"""Извлекает адрес, содержащий г. или Г."""
if not text:
return ""
# Ищем текст с "г." или "Г."
if re.search(r'[гГ]\.', text):
return text.strip()
return ""
def extract_email(text):
"""Извлекает email из текста и убирает пробелы после @"""
if not text:
return ""
# Убираем пробелы после @
text = re.sub(r'@\s+', '@', text)
# Ищем паттерн email
email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
match = re.search(email_pattern, text)
return match.group(0) if match else ""
def extract_phone(text):
"""Извлекает телефон из текста"""
if not text:
return ""
# Убираем лишние пробелы
return text.strip()
def parse_contact_data(cells):
"""Парсит данные контакта из ячеек таблицы"""
# Объединяем весь текст из всех ячеек для анализа
all_text = ' '.join(cells)
# ВАЖНО: Парсим только строки с email!
has_email = '@' in all_text
if not has_email:
return None
contact = {
'Имя': '',
'Фамилия': '',
'Отчество': '',
'Организация': '',
'Телефон': '',
'E-mail': ''
}
# Ищем email
for cell in cells:
email = extract_email(cell)
if email:
contact['E-mail'] = email
break
# Ищем организацию/имя в кавычках «»
organization_found = False
for cell in cells:
quoted_match = re.search(r'«([^»]+)»', cell)
if quoted_match:
contact['Организация'] = quoted_match.group(1).strip()
organization_found = True
break
# Если не нашли в кавычках, ищем название ЗАГЛАВНЫМИ буквами
if not organization_found:
for cell in cells:
# Ищем текст заглавными буквами (название организации обычно так)
# Исключаем строки с email и телефонами
if cell and not '@' in cell and not re.search(r'8\s*\(\d+\)', cell):
# Проверяем, есть ли заглавные слова
upper_words = re.findall(r'[А-ЯЁA-Z][А-ЯЁA-Z\s\-\.]+', cell)
if upper_words:
# Берем самое длинное совпадение
longest = max(upper_words, key=len).strip()
if len(longest) > 10: # Минимум 10 символов для названия
contact['Организация'] = longest
organization_found = True
break
# Ищем адрес (содержит г. или Г.) и добавляем к организации
for cell in cells:
address_match = re.search(r'\d{6},\s*[гГ]\.\s*[^,]+(?:,\s*[^,]+)*', cell)
if address_match:
address = address_match.group(0)
if contact['Организация'] and address not in contact['Организация']:
contact['Организация'] += ', ' + address
elif not contact['Организация']:
contact['Организация'] = address
break
# Ищем телефон (только основной, если есть)
for cell in cells:
# Ищем паттерн телефона
phone_match = re.search(r'8\s*\(\d+\)\s*[\d\-]+', cell)
if phone_match:
contact['Телефон'] = phone_match.group(0).strip()
break
return contact
def parse_phone_book():
"""Парсит телефонную книгу из Word документа и сохраняет в CSV"""
# Открываем документ
doc = docx.Document('./04_Телефонный справочник_МАКСИМ.docx')
# Список для хранения контактов
contacts = []
# Обрабатываем каждую таблицу в документе
for table in doc.tables:
# Пропускаем первую строку (заголовок), если она есть
rows = table.rows
for i, row in enumerate(rows):
cells = [cell.text.strip() for cell in row.cells]
# Пропускаем пустые строки или заголовки
if not cells or not any(cells):
continue
# Проверяем, что это не заголовок таблицы
if i == 0 and ('имя' in cells[0].lower() or 'фамилия' in ' '.join(cells).lower()):
continue
# Парсим данные контакта
contact = parse_contact_data(cells)
# Добавляем только если есть email и данные
if contact and any(contact.values()):
contacts.append(contact)
# Записываем в CSV файл
with open('contacts.csv', 'w', encoding='utf-8', newline='') as csvfile:
fieldnames = ['Имя', 'Фамилия', 'Отчество', 'Организация', 'Телефон', 'E-mail']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=';')
# Записываем заголовок
writer.writeheader()
# Записываем все контакты
writer.writerows(contacts)
print(f"Успешно обработано {len(contacts)} контактов")
print(f"Данные сохранены в файл contacts.csv")
return contacts
def export_for_gmail():
"""Экспортирует контакты в формате для Gmail"""
# Читаем существующий CSV файл
contacts = []
with open('contacts.csv', 'r', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile, delimiter=';')
contacts = list(reader)
# Создаем CSV в формате Gmail
with open('contacts_gmail.csv', 'w', encoding='utf-8', newline='') as csvfile:
# Gmail использует специальные заголовки
fieldnames = ['Name', 'Given Name', 'Additional Name', 'Family Name',
'Organization 1 - Name', 'Phone 1 - Value', 'E-mail 1 - Value']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for contact in contacts:
# Очищаем название организации от многострочного текста
org = contact['Организация']
if org:
org = org.split('\n')[0].strip()
org = re.sub(r',\s*\d{6},.*$', '', org)
org = org.rstrip(',').strip()
# Формируем полное имя
full_name = f"{contact['Фамилия']} {contact['Имя']} {contact['Отчество']}".strip()
gmail_contact = {
'Name': org if org else full_name,
'Given Name': contact['Имя'],
'Additional Name': contact['Отчество'],
'Family Name': contact['Фамилия'],
'Organization 1 - Name': org,
'Phone 1 - Value': contact['Телефон'],
'E-mail 1 - Value': contact['E-mail']
}
writer.writerow(gmail_contact)
print(f"\n✅ Файл для Gmail создан: contacts_gmail.csv ({len(contacts)} контактов)")
print("📧 Импортируйте его в Gmail: Контакты -> Импорт -> Выберите файл")
return contacts
def export_for_mailru():
"""Экспортирует контакты в формате для Mail.ru"""
# Читаем существующий CSV файл
contacts = []
with open('contacts.csv', 'r', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile, delimiter=';')
contacts = list(reader)
# Создаем CSV в формате Mail.ru (простой формат)
with open('contacts_mailru.csv', 'w', encoding='utf-8', newline='') as csvfile:
# Mail.ru использует простые заголовки
fieldnames = ['First Name', 'Last Name', 'E-mail Address', 'Home Phone', 'Company']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for contact in contacts:
# Очищаем название организации от многострочного текста
org = contact['Организация']
if org:
org = org.split('\n')[0].strip()
org = re.sub(r',\s*\d{6},.*$', '', org)
org = org.rstrip(',').strip()
mailru_contact = {
'First Name': contact['Имя'] if contact['Имя'] else org,
'Last Name': contact['Фамилия'],
'E-mail Address': contact['E-mail'],
'Home Phone': contact['Телефон'],
'Company': org
}
writer.writerow(mailru_contact)
print(f"\n✅ Файл для Mail.ru создан: contacts_mailru.csv ({len(contacts)} контактов)")
print("📧 Импортируйте его в Mail.ru: Настройки -> Контакты -> Импорт")
return contacts
def export_to_vcard():
"""Экспортирует контакты в формат VCard (.vcf)"""
# Читаем существующий CSV файл
contacts = []
with open('contacts.csv', 'r', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile, delimiter=';')
contacts = list(reader)
with open('contacts.vcf', 'w', encoding='utf-8') as vcf_file:
for contact in contacts:
# Очищаем название организации от многострочного текста
org = contact['Организация']
if org:
org = org.split('\n')[0].strip()
org = re.sub(r',\s*\d{6},.*$', '', org)
org = org.rstrip(',').strip()
# Формируем VCard для каждого контакта
vcf_file.write("BEGIN:VCARD\n")
vcf_file.write("VERSION:3.0\n")
# Имя
if contact['Фамилия'] or contact['Имя']:
vcf_file.write(f"FN:{contact['Фамилия']} {contact['Имя']} {contact['Отчество']}\n".strip() + "\n")
vcf_file.write(f"N:{contact['Фамилия']};{contact['Имя']};{contact['Отчество']};;\n")
else:
# Если нет имени, используем организацию
vcf_file.write(f"FN:{org}\n")
# Организация
if org:
vcf_file.write(f"ORG:{org}\n")
# Email
if contact['E-mail']:
vcf_file.write(f"EMAIL;TYPE=INTERNET:{contact['E-mail']}\n")
# Телефон
if contact['Телефон']:
vcf_file.write(f"TEL;TYPE=WORK,VOICE:{contact['Телефон']}\n")
vcf_file.write("END:VCARD\n")
print(f"\n✅ Файл VCard создан: contacts.vcf ({len(contacts)} контактов)")
print("📱 Импортируйте его в почтовый клиент или телефон")
return contacts
if __name__ == "__main__":
print("=" * 60)
print("ПАРСЕР ТЕЛЕФОННОЙ КНИГИ")
print("=" * 60)
# Сначала парсим Word документ
print("\n📖 Парсинг телефонной книги из Word...")
contacts = parse_phone_book()
# Затем создаем файлы для импорта
print("\n" + "=" * 60)
print("СОЗДАНИЕ ФАЙЛОВ ДЛЯ ИМПОРТА")
print("=" * 60)
export_for_mailru()
export_for_gmail()
export_to_vcard()
# Выводим статистику
print("\n" + "=" * 60)
print("ПРИМЕРЫ КОНТАКТОВ:")
print("=" * 60)
for i, contact in enumerate(contacts[:5], 1):
org = contact['Организация'].split('\n')[0][:50]
print(f"{i}. {org}... - {contact['E-mail']}")
print("\n" + "=" * 60)
print("✅ ГОТОВО! Используйте файлы для импорта:")
print(" 📧 contacts_mailru.csv - для Mail.ru")
print(" 📧 contacts_gmail.csv - для Gmail, Outlook")
print(" 📱 contacts.vcf - для Apple Mail, телефонов")
print("=" * 60)