作業四

早八打酱油發表於2024-11-12

作業一

要求:
▪ 熟練掌握 Selenium 查詢 HTML 元素、爬取 Ajax 網頁資料、等待 HTML 元素等內
容。
▪ 使用 Selenium 框架+ MySQL 資料庫儲存技術路線爬取“滬深 A 股”、“上證 A 股”、
“深證 A 股”3 個板塊的股票資料資訊。
o 候選網站:東方財富網:
http://quote.eastmoney.com/center/gridlist.html#hs_a_board
o 輸出資訊:MYSQL 資料庫儲存和輸出格式如下,表頭應是英文命名例如:序號
id,股票程式碼:bStockNo……,由同學們自行定義設計表頭
部分關鍵程式碼

def insert_stock_data(cursor, stock_data):
    cursor.execute("""
    INSERT INTO stocks (
        股票程式碼, 股票名稱, 最新價, 漲跌幅, 漲跌額, 
        成交量, 成交額, 振幅, 最高, 最低, 今開, 昨收
    ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
    """, (
        stock_data['股票程式碼'], stock_data['股票名稱'], stock_data['最新價'], stock_data['漲跌幅'],
        stock_data['漲跌額'], stock_data['成交量'], stock_data['成交額'], stock_data['振幅'],
        stock_data['最高'], stock_data['最低'], stock_data['今開'], stock_data['昨收']
    ))

這部分程式碼用於將爬取到的股票資料按照順序填入表格

# 爬取所有頁的資料
data = []

# 假設頁面最多會翻10頁,可以根據需要修改
page = 1
while True:
    # 獲取當前頁面的所有股票資料
    rows = driver.find_elements(By.XPATH, "//table[@id='table_wrapper-table']/tbody/tr")

    # 如果沒有資料,停止爬取
    if not rows:
        print("沒有更多資料,停止爬取。")
        break

    # 遍歷每一行,提取股票資訊
    for row in rows:
        cols = row.find_elements(By.TAG_NAME, "td")
        if len(cols) > 1:
            stock_data = {
                '股票程式碼': cols[1].text,  # 股票程式碼
                '股票名稱': cols[2].text,  # 股票名稱
                '最新價': float(cols[4].text.replace(",", "")) if cols[4].text else 0.0,  # 最新價
                '漲跌幅': float(cols[5].text.replace("%", "")) if cols[5].text else 0.0,  # 漲跌幅
                '漲跌額': float(cols[6].text.replace(",", "")) if cols[6].text else 0.0,  # 漲跌額
                '成交量': parse_volume(cols[7].text),  # 使用parse_volume函式處理成交量
                '成交額': parse_amount(cols[8].text),  # 使用parse_amount函式處理成交額
                '振幅': float(cols[9].text.replace("%", "")) if cols[9].text else 0.0,  # 振幅
                '最高': float(cols[10].text.replace(",", "")) if cols[10].text else 0.0,  # 最高
                '最低': float(cols[11].text.replace(",", "")) if cols[11].text else 0.0,  # 最低
                '今開': float(cols[12].text.replace(",", "")) if cols[12].text else 0.0,  # 今開
                '昨收': float(cols[13].text.replace(",", "")) if cols[13].text else 0.0  # 昨收
            }
            data.append(stock_data)

            # 將資料插入到資料庫
            insert_stock_data(cursor, stock_data)

    # 等待翻頁按鈕可點選
    try:
        WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='next']"))
        )

        # 點選翻頁按鈕,載入下一頁資料
        next_button = driver.find_element(By.XPATH, "//a[@class='next']")
        next_button.click()

        # 等待頁面載入
        time.sleep(3)

        page += 1

        if page > 10:  # 假設只爬取前10頁
            print("爬取結束,已到達最大頁數。")
            break

    except Exception as e:
        print(f"翻頁失敗或超時: {e}")
        break  # 如果發生任何異常則停止翻頁

這部分程式碼用於爬取網站的相關股票資料
結果展示
image
image
image
心得體會
在這次資料爬取和資料庫儲存的過程中,我學到了很多關於如何使用 Selenium 和 MySQL 進行資料抓取和管理的知識。透過使用 Selenium,能夠模擬瀏覽器操作,自動化地從網頁上提取資料,這對處理大量網頁內容和需要頻繁更新的資料尤為重要。此外,使用 MySQL 來儲存資料,不僅提高了資料的永續性,還方便了後續的資料分析和處理。透過設定字符集為 utf8mb4,確保了中文資料的正確儲存和顯示。
在處理頁面翻頁時,利用 WebDriverWait 和 EC.element_to_be_clickable 等 Selenium 技巧,提高了程式的穩定性和效率。對成交量和成交額等資料的處理,也透過自定義函式進行轉換和解析,使得資料能夠符合資料庫儲存的標準。這次實踐讓我對如何處理網頁抓取、資料解析、資料庫操作有了更深入的瞭解。
同時,在設計資料庫時,採用中文列名,使得資料更加易於理解和管理。儘管過程中遇到了一些挑戰,如翻頁失敗和超時問題,但透過不斷除錯和最佳化,最終順利完成了任務。總體來說,這次經歷不僅讓我加深了對資料抓取技術的理解,也提高了我在實際專案中應用技術的能力。

作業二

要求:
熟練掌握 Selenium 查詢HTML元素、實現使用者模擬登入、爬取Ajax網頁資料、等待HTML元素等內容。
使用Selenium框架+MySQL爬取中國mooc網課程資源資訊(課程號、課程名稱、學校名稱、主講教師、團隊成員、參加人數、課程進度、課程簡介)
候選網站:中國mooc網:https://www.icourse163.org
輸出資訊:MYSQL資料庫儲存和輸出格式
部分核心程式碼展示

# 開啟 iCourse163 網站
driver.get('https://www.icourse163.org/')
time.sleep(1)

# 定位並點選登入按鈕
button = driver.find_element(By.XPATH, '//*[@id="app"]/div/div/div[1]/div[3]/div[3]/div')
button.click()
time.sleep(1)

# 切換到登入 iframe
frame = driver.find_element(By.XPATH, "//div[@class='ux-login-set-container']//iframe")
driver.switch_to.frame(frame)

這部分用於模擬使用者登入到mook平臺

# 獲取課程連結元素列表
link_list = driver.find_elements(By.XPATH, '//div[@class="u-clist f-bgw f-cb f-pr j-href ga-click"]')

# 遍歷課程連結元素列表
for link in link_list:
    # 獲取課程名稱
    course_name = link.find_element(By.XPATH, './/span[@class=" u-course-name f-thide"]').text
    # 獲取學校名稱
    school_name = link.find_element(By.XPATH, './/a[@class="t21 f-fc9"]').text
    # 獲取主講老師
    teacher = link.find_element(By.XPATH, './/a[@class="f-fc9"]').text
    try:
        # 獲取教師團隊成員
        team_member = link.find_element(By.XPATH, './/span[@class="f-fc9"]/span').text
        team_member = teacher + ' 、' + team_member
    except Exception:
        team_member = 'none'
    # 獲取參加人數並去除'參加'字樣
    attendees = link.find_element(By.XPATH, './/span[@class="hot"]').text.replace('參加', '')
    # 獲取課程進度
    process = link.find_element(By.XPATH, './/span[@class="txt"]').text
    # 獲取課程簡介
    introduction = link.find_element(By.XPATH, './/span[@class="p5 brief f-ib f-f0 f-cb"]').text

    # 將資料插入 MySQL 資料庫
    cursor.execute('''
        INSERT INTO courses (課程名稱, 學校名稱, 老師, 教師團隊, 參加人數, 課程進度, 課程簡介)
        VALUES (%s, %s, %s, %s, %s, %s, %s)
    ''', (course_name, school_name, teacher, team_member, attendees, process, introduction))
    conn.commit()

這部分用於爬取mook的課程內容
執行結果image
心得體會
在進行資料庫操作和使用 Selenium 自動化抓取網頁資料的過程中,我深入體會到了程式設計與實際應用結合的重要性。首先,在進行資料抓取時,我意識到網頁結構的複雜性和動態載入內容的挑戰,使用 Selenium 時切換 iframe 和等待元素載入是非常關鍵的步驟。這讓我對網頁的 DOM 結構和網路請求有了更深的理解。
其次,在使用 MySQL 儲存抓取的資料時,我發現資料庫設計的重要性。透過合理的表結構和資料型別的選擇,不僅能保證資料儲存的效率,還能提高後續查詢和管理的便捷性。我還意識到,面對不同資料庫(如 MySQL 和 SQLite)時,連線方式、查詢語法和許可權管理會有些許差異,因此需要根據實際需求靈活調整。
此外,透過實際操作,我對程式設計中常見的問題和錯誤有了更多的應對經驗。例如,遇到庫或驅動版本不匹配時,如何快速定位問題並解決,如何除錯程式的每一步操作,這些經驗對於提高開發效率非常有幫助。
總的來說,透過實踐,我不僅提高了程式設計技能,還對如何高效地從網頁抓取資料並進行儲存和分析有了更深的理解。這將為未來更多的專案和挑戰打下堅實的基礎。

相關文章