Search

๋„ค์ด๋ฒ„ ์ด๋ฉ”์ผ ์ž๋™ํ™” ํ”„๋กœ๊ทธ๋žจ

๋„ค์ด๋ฒ„ ์ด๋ฉ”์ผ ์ž๋™ํ™” ํ”„๋กœ๊ทธ๋žจ

๋„ค์ด๋ฒ„์— ์ž๋™์œผ๋กœ ๋กœ๊ทธ์ธํ•ด์„œ, ์ค€๋น„๋œ ์ด๋ฉ”์ผ์„ ์ž๋™์œผ๋กœ ๋ณด๋‚ด๋Š” ํ”„๋กœ๊ทธ๋žจ

ํ”„๋กœ๊ทธ๋žจ

1
2

ํ”„๋กฌํ”„ํŠธ

ํŽ˜๋ฅด์†Œ๋‚˜ - ํŒŒ์ด์ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•™์Šต์ž ์ž‘์—… - ๋„ค์ด๋ฒ„ ์ด๋ฉ”์ผ ์ž๋™ํ™” ํ”„๋กœ๊ทธ๋žจ ๊ฐœ๋ฐœ ๋งฅ๋ฝ - ์–ธ์–ด : ํŒŒ์ด์ฌ - ๋ฒ„์ „ : 3.13 - ๊ตฌ์กฐ : GUI ํ”„๋กœ๊ทธ๋žจ - ๊ธฐ๋Šฅ * MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ด๋ฉ”์ผ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ - ๋ฐ›๋Š”์‚ฌ๋žŒ ๋ฉ”์ผ์ฃผ์†Œ, ์ œ๋ชฉ, ๋‚ด์šฉ, ์ƒํƒœ(์™„๋ฃŒ,์ „์†ก์ „) - ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์‹œ, email ํ…Œ์ด๋ธ” ์—†์œผ๋ช… ์ƒ์„ฑ - database=python, useranme=python, password=123456 * ์ผ๊ด„์ „์†ก ๊ธฐ๋Šฅ - "์ผ๊ด„์ „์†ก" ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ด๋ฉ”์ผ ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜์—ฌ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฉ”์ผ์„ ์ „์†กํ•˜๋Š” ๊ธฐ๋Šฅ - ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ํ™•์ธ ํ›„, ๋ฉ”์ผ ์“ฐ๊ธฐ ์ง„ํ–‰ - ์ด๋ฉ”์ผ ์“ฐ๊ธฐ url : https://mail.naver.com/v2/new - ์ž…๋ ฅ ํƒœ๊ทธ * ์ด๋ฉ”์ผ : id="recipient_input_element" * ์ œ๋ชฉ : id="subject_title" * ๋‚ด์šฉ : class="workseditor-content" - ์ „์†ก ๋ฒ„ํŠผ * class="button_write_task" - ์ „์†ก ํ›„, https://mail.naver.com/v2/new/done ๊ฒฝ๋กœ๋กœ ์ด๋™๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ https://mail.naver.com/v2/new/done ์™„๋ฃŒ ํŽ˜์ด์ง€๋กœ ์ด๋™ ๋˜๋ฉด ํ•ด๋‹น ์ด๋ฉ”์ผ ์ •๋ณด๋Š” DB์—์„œ status ์™„๋ฃŒ๋กœ ๋ณ€๊ฒฝํ›„, ์™„๋ฃŒ๊ฐ€ ์•„๋‹Œ ๋‹ค์Œ ์ด๋ฉ”์ผ ๋ณด๋‚ด๊ธฐ ์ง„ํ–‰ - ๋ชจ๋“  ์ด๋ฉ”์ผ ์ „์†ก์ด ์™„๋ฃŒ๋˜๋ฉด, ํŒ์—…์ฐฝ์œผ๋กœ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ * ๋„ค์ด๋ฒ„ ์ž๋™ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ - ์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด๋†“๊ณ  ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ, ๋„ค์ด๋ฒ„์— ๋กœ๊ทธ์ธ url : https://nid.naver.com/nidlogin.login?mode=form ํ˜•์‹ - ํŒŒ์ด์ฌ GUI ํ”„๋กœ๊ทธ๋žจ์—์„œ ํฌ๋กฌ ์›น๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ œ์–ดํ•˜๋Š” ๋ฐฉ์‹ ์˜ˆ์‹œ - ์•„์ด๋”” ๋น„๋ฒˆ ์ž…๋ ฅ ํ›„, ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋„ค์ด๋ฒ„์— ๋กœ๊ทธ์ธ - ๋ฉ”์ผ ๋“ฑ๋ก ๋ฒ„ํŠผ ํด๋ฆญ ํ›„, ์ด๋ฉ”์ผ์ฃผ์†Œ, ์ œ๋ชฉ, ๋‚ด์šฉ ์ž‘์„ฑ ํ›„ ์ €์žฅํ•˜๋ฉด email ํ…Œ์ด๋ธ”์— ์ด๋ฉ”์ผ ์ •๋ณด ๋“ฑ๋ก - ๋ฉ”์ผ ์ •๋ณด ์‚ญ์ œ, ์ˆ˜์ • ์ฒ˜๋ฆฌ - "์ผ๊ด„ ์ „์†ก" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ, ์ฝ์–ด๋“œ๋ฆฐ ์ด๋ฉ”์ผ ๋ชฉ๋ก์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ „์†ก ์บ”๋ฒ„์Šค ๋ชจ๋“œ๋กœ ์‘๋‹ต
Plain Text
๋ณต์‚ฌ

์ฝ”๋“œ

import tkinter as tk from tkinter import messagebox, simpledialog, Toplevel, Label, Entry, Text, Button, END from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import mysql.connector import time # DB ์„ค์ • DB_CONFIG = { 'host': 'localhost', 'user': 'python', 'password': '123456', 'database': 'python' } # email ํ…Œ์ด๋ธ” ์ƒ์„ฑ ํ•จ์ˆ˜ def init_db(): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS email ( id INT AUTO_INCREMENT PRIMARY KEY, recipient VARCHAR(255), subject VARCHAR(255), content TEXT, status VARCHAR(50) DEFAULT '์ „์†ก์ „' ) """) conn.commit() cursor.close() conn.close() # ์ด๋ฉ”์ผ ๋“ฑ๋ก ํ•จ์ˆ˜ def add_email(recipient, subject, content): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("INSERT INTO email (recipient, subject, content) VALUES (%s, %s, %s)", (recipient, subject, content)) conn.commit() cursor.close() conn.close() # ์ด๋ฉ”์ผ ์ˆ˜์ • ํ•จ์ˆ˜ def update_email(email_id, recipient, subject, content): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute(""" UPDATE email SET recipient=%s, subject=%s, content=%s WHERE id=%s """, (recipient, subject, content, email_id)) conn.commit() cursor.close() conn.close() # ์ด๋ฉ”์ผ ์‚ญ์ œ ํ•จ์ˆ˜ def delete_email(email_id): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("DELETE FROM email WHERE id=%s", (email_id,)) conn.commit() cursor.close() conn.close() # ์ด๋ฉ”์ผ ๋ฆฌ์ŠคํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ (์ „์†ก์ „ ์ƒํƒœ๋งŒ) def get_pending_emails(): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor(dictionary=True) cursor.execute("SELECT * FROM email WHERE status='์ „์†ก์ „'") emails = cursor.fetchall() cursor.close() conn.close() return emails # ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜ def mark_email_as_sent(email_id): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("UPDATE email SET status='์™„๋ฃŒ' WHERE id=%s", (email_id,)) conn.commit() cursor.close() conn.close() # ์ด๋ฉ”์ผ ์ „์†ก ํ•จ์ˆ˜ def send_emails(driver): emails = get_pending_emails() for email in emails: driver.get("https://mail.naver.com/v2/new") WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "recipient_input_element"))).send_keys(email['recipient']) driver.find_element(By.ID, "subject_title").send_keys(email['subject']) # ๋‚ด์šฉ ์ž…๋ ฅ์„ innerHTML ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ# ๋‚ด์šฉ ์ž…๋ ฅ์„ innerHTML ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ (์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋กœ ์ง€์ •) # content_elements = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, "workseditor-content"))) # if content_elements: # driver.execute_script("arguments[0].innerHTML = arguments[1];", content_elements[0], email['content'].replace('\n', '<br>')) driver.find_element(By.CLASS_NAME, "button_write_task").click() WebDriverWait(driver, 10).until(EC.url_contains("/v2/new/done")) mark_email_as_sent(email['id']) time.sleep(1) messagebox.showinfo("์™„๋ฃŒ", "๋ชจ๋“  ์ด๋ฉ”์ผ ์ „์†ก์„ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค.") # ๋กœ๊ทธ์ธ ํ•จ์ˆ˜ def login_to_naver(driver, user_id, user_pw): driver.get("https://nid.naver.com/nidlogin.login?mode=form") WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "id"))).send_keys(user_id) driver.find_element(By.ID, "pw").send_keys(user_pw) driver.find_element(By.ID, "log.login").click() # GUI ํ”„๋กœ๊ทธ๋žจ class EmailApp: def __init__(self, root): self.root = root self.root.title("๋„ค์ด๋ฒ„ ์ด๋ฉ”์ผ ์ž๋™ํ™”") tk.Label(root, text="์•„์ด๋””").grid(row=0, column=0) self.entry_id = tk.Entry(root) self.entry_id.grid(row=0, column=1) tk.Label(root, text="๋น„๋ฐ€๋ฒˆํ˜ธ").grid(row=1, column=0) self.entry_pw = tk.Entry(root, show='*') self.entry_pw.grid(row=1, column=1) tk.Button(root, text="๋กœ๊ทธ์ธ", command=self.login).grid(row=2, column=0, columnspan=2) tk.Button(root, text="๋ฉ”์ผ ๋“ฑ๋ก", command=self.register_email).grid(row=3, column=0, columnspan=2) tk.Button(root, text="์ผ๊ด„ ์ „์†ก", command=self.bulk_send).grid(row=4, column=0, columnspan=2) self.driver = None def login(self): user_id = self.entry_id.get() user_pw = self.entry_pw.get() self.driver = webdriver.Chrome() login_to_naver(self.driver, user_id, user_pw) def register_email(self): def save(): recipient = entry_recipient.get() subject = entry_subject.get() content = text_content.get("1.0", END).strip() if recipient and subject and content: add_email(recipient, subject, content) popup.destroy() popup = Toplevel(self.root) popup.title("๋ฉ”์ผ ๋“ฑ๋ก") Label(popup, text="๋ฐ›๋Š”์‚ฌ๋žŒ").grid(row=0, column=0) entry_recipient = Entry(popup, width=40) entry_recipient.grid(row=0, column=1) Label(popup, text="์ œ๋ชฉ").grid(row=1, column=0) entry_subject = Entry(popup, width=40) entry_subject.grid(row=1, column=1) Label(popup, text="๋‚ด์šฉ").grid(row=2, column=0) text_content = Text(popup, width=40, height=10) text_content.grid(row=2, column=1) Button(popup, text="์ €์žฅ", command=save).grid(row=3, column=0, columnspan=2) def bulk_send(self): if not self.driver: messagebox.showerror("์˜ค๋ฅ˜", "๋จผ์ € ๋กœ๊ทธ์ธ์„ ํ•ด์ฃผ์„ธ์š”.") return send_emails(self.driver) if __name__ == '__main__': init_db() root = tk.Tk() app = EmailApp(root) root.mainloop()
Python
๋ณต์‚ฌ