iT邦幫忙

2025 iThome 鐵人賽

DAY 30
0
Software Development

從零開始學 Python系列 第 30

Day 30 – 專案實作:迷你爬蟲工具

  • 分享至 

  • xImage
  •  

經過 29 天的學習與準備,今天終於迎來 IT 鐵人賽的最後一天!
我將前面學到的 requests、BeautifulSoup 和 tkinter 全部組合,完成了一個小型桌面應用程式:迷你爬蟲工具。

一、完整程式碼

import requests
from bs4 import BeautifulSoup
import tkinter as tk
from tkinter import filedialog

def fetch_data(mode="title"):
    url = entry.get().strip()
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/114.0.0.0 Safari/537.36"
    }
    try:
        resp = requests.get(url, headers=headers, timeout=10)
        resp.raise_for_status()
        soup = BeautifulSoup(resp.text, "html.parser")

        text_box.delete("1.0", tk.END)

        if mode == "title":
            title = soup.title.string if soup.title else "找不到標題"
            text_box.insert(tk.END, f"標題:{title}\n")

        elif mode == "links":
            links = soup.find_all("a")
            if not links:
                text_box.insert(tk.END, "找不到任何超連結\n")
            for i, link in enumerate(links[:30], 1):  # 顯示前 30 筆
                href = link.get("href")
                if href:
                    text_box.insert(tk.END, f"{i}. {link.get_text(strip=True)} → {href}\n")

    except Exception as e:
        text_box.delete("1.0", tk.END)
        text_box.insert(tk.END, f"錯誤:{e}\n")

def save_result():
    content = text_box.get("1.0", tk.END).strip()
    if not content:
        return
    file_path = filedialog.asksaveasfilename(
        defaultextension=".txt",
        filetypes=[("文字檔", "*.txt"), ("所有檔案", "*.*")]
    )
    if file_path:
        with open(file_path, "w", encoding="utf-8") as f:
            f.write(content)

# GUI
window = tk.Tk()
window.title("迷你爬蟲工具")
window.geometry("700x500")

tk.Label(window, text="請輸入網址:").pack(pady=5)
entry = tk.Entry(window, width=60)
entry.pack(pady=5)

frame = tk.Frame(window)
frame.pack(pady=5)

btn1 = tk.Button(frame, text="抓標題", command=lambda: fetch_data("title"))
btn1.grid(row=0, column=0, padx=5)

btn2 = tk.Button(frame, text="抓連結", command=lambda: fetch_data("links"))
btn2.grid(row=0, column=1, padx=5)

btn3 = tk.Button(frame, text="儲存結果", command=save_result)
btn3.grid(row=0, column=2, padx=5)

text_box = tk.Text(window, wrap="word", height=20)
text_box.pack(padx=10, pady=10, fill="both", expand=True)

scrollbar = tk.Scrollbar(text_box, command=text_box.yview)
scrollbar.pack(side="right", fill="y")
text_box.config(yscrollcommand=scrollbar.set)

window.mainloop()

二、功能展示

  • 輸入網址 → https://www.python.org

  • 點擊「抓標題」 → 顯示網頁標題
    螢幕擷取畫面 2025-09-01 140019

  • 點擊「抓連結」 → 顯示所有超連結
    螢幕擷取畫面 2025-09-01 140053

  • 點擊「儲存結果」 → 把結果存成文字檔
    螢幕擷取畫面 2025-09-01 140256

三、學習心得

30 天的挑戰結束了!從第一週基本語法與控制結構(安裝環境、變數、條件判斷、迴圈),第二週資料結構與函式(list、dict、tuple、函示定義),到第三週字串、例外、模組(字串處理、try/except、模組使用)、第四週實戰應用與小專案(API、爬蟲、自動化、GUI/小遊戲)。每一天都在累積一點點能力,最後把這些知識拼湊成一個可以運作的應用程式。
雖然這個「迷你爬蟲工具」功能很簡單,但它代表了我這 30 天的成長。從一開始對 Python 完全不了解,到最後能自己設計並完成一個小專案,這段過程就是最有價值的收穫!

結語

30 天的學習挑戰,從零基礎到完成專案,這段旅程不只是技術上的成長,更是堅持的證明!
我想很誠實地說:這一路走來,程式碼大部分還是需要靠 GPT 的協助完成(有時候有放在學習心得分享今天哪裡出錯,GPT幫忙解析錯誤以及如何修正)。要靠自己從頭到尾完全正確地寫出來,對目前的我來說還有點難。但這不代表學習是失敗的,反而是讓我意識到,工具在這裡取決於你怎麼使用。可以靠工具學習,也可以讓工具取代自己。就如同隊員說的:「AI 不是取代人類,而是放大人類的價值;關鍵在於,誰懂得如何與它共舞。」另外還有如何在逆境中學習,找到適合自己的方式:「萬物皆向前行,唯我選擇逆向;順流者尋答案,逆向者尋真相;順行是追隨,逆向是思索。這不是反叛,而是我的方式去理解世界。」關於AI以及逆向的知識,也歡迎大家去看看另外兩個隊友的作品~~ 內容也非常精采有程度ㄛ!
透過 GPT 的範例、修改建議、錯誤排查,我能夠更快地理解程式的運作方式,並且能快速對照以前學習Java時相同單元同時複習!
但未來的目標還是要逐步減少依賴,讓更多程式能自己獨立完成!
謝謝一路上陪伴我的讀者,也希望這個系列能帶給同樣在學習 Python 的人一些幫助!
下台一鞠躬!


上一篇
Day 29 – 專案規劃:迷你爬蟲工具
系列文
從零開始學 Python30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言