2024資料採集與融合技術實踐第四次作業

chenoojkk發表於2024-11-12
這個作業屬於哪個課程 <首頁 - 2024資料採集與融合技術實踐 - 福州大學 - 班級部落格 - 部落格園 (cnblogs.com)>
這個作業要求在哪裡 <作業4 - 作業 - 2024資料採集與融合技術實踐 - 班級部落格 - 部落格園 (cnblogs.com)>
學號 <102202126>

一、作業內容

作業①

  • 要求:

    • 熟練掌握 Selenium 查詢HTML元素、爬取Ajax網頁資料、等待HTML元素等內容。
    • 使用Selenium框架+ MySQL資料庫儲存技術路線爬取“滬深A股”、“上證A股”、“深證A股”3個板塊的股票資料資訊。
  • 程式碼如下

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver import ChromeService
    from selenium.webdriver import ChromeOptions
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    import time
    import pymysql
    chrome_options = ChromeOptions()
    chrome_options.add_argument('--disable-gpu')
    chrome_options.binary_location = r'C:\Users\20733\AppData\Local\Google\Chrome\Application\chrome.exe'
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')
    service = ChromeService(executable_path='C:/Users/20733/AppData/Local/Programs/Python/Python313/Scripts/chromedriver.exe')
    driver = webdriver.Chrome(service=service,options=chrome_options)
    driver.maximize_window()
    
    # 連線scrapy資料庫,建立表
    try:
        db = pymysql.connect( host='127.0.0.1', user='root', passwd='Cjkmysql.', port=3306, charset='utf8',
            database='chenoojkk',)
        cursor = db.cursor()
        cursor.execute('DROP TABLE IF EXISTS stockT')
        sql = '''CREATE TABLE stockT(num varchar(32),id varchar(12),name varchar(32),Latest_quotation varchar(32),Chg varchar(12),up_down_amount varchar(12),
                turnover varchar(16),transaction_volume varchar(16),amplitude varchar(16),highest varchar(32), lowest varchar(32),today varchar(32),yesterday varchar(32))'''
        cursor.execute(sql)
    except Exception as e:
        print(e)
    
    def spider(page_num):
        cnt = 0
        while cnt < page_num:
            spiderOnePage()
            driver.find_element(By.XPATH,'//a[@class="next paginate_button"]').click()
            cnt +=1
        time.sleep(2)
    
    # 爬取一個頁面的資料
    def spiderOnePage():
        time.sleep(3)
        trs = driver.find_elements(By.XPATH,'//table[@id="table_wrapper-table"]//tr[@class]')
        for tr in trs:
            tds = tr.find_elements(By.XPATH,'.//td')
            num = tds[0].text
            id = tds[1].text
            name = tds[2].text
            Latest_quotation = tds[6].text
            Chg = tds[7].text
            up_down_amount = tds[8].text
            turnover = tds[9].text
            transaction_volume = tds[10].text
            amplitude = tds[11].text
            highest = tds[12].text
            lowest = tds[13].text
            today = tds[14].text
            yesterday = tds[15].text
            cursor.execute('INSERT INTO stockT VALUES ("%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s")' % (num,id,name,Latest_quotation,
                                                    Chg,up_down_amount,turnover,transaction_volume,amplitude,highest,lowest,today,yesterday))
            db.commit()
    
    # 訪問東方財富網
    driver.get('https://www.eastmoney.com/')
    # 訪問行情中心
    driver.get(WebDriverWait(driver,15,0.48).until(EC.presence_of_element_located((By.XPATH,'/html/body/div[6]/div/div[2]/div[1]/div[1]/a'))).get_attribute('href'))
    # 訪問滬深京A股
    driver.get(WebDriverWait(driver,15,0.48).until(EC.presence_of_element_located((By.ID,'menu_hs_a_board'))).get_attribute('href'))
    # 爬取兩頁的資料
    spider(2)
    driver.back()
    
    # 訪問上證A股
    driver.get(WebDriverWait(driver,15,0.48).until(EC.presence_of_element_located((By.ID,'menu_sh_a_board'))).get_attribute('href'))
    spider(2)
    driver.back()
    
    # 訪問深證A股
    driver.get(WebDriverWait(driver,15,0.48).until(EC.presence_of_element_located((By.ID,'menu_sz_a_board'))).get_attribute('href'))
    spider(2)
    
    try:
        cursor.close()
        db.close()
    except:
        pass
    time.sleep(3)
    driver.quit()
    
  • 輸出資訊:

  • Gitee資料夾連結:陳家凱第四次實踐作業

  • 心得體會:

    • 在實際操作中,使用Selenium爬蟲抓取股票資料時,效能和效率之間需要做一定的平衡。雖然Selenium能夠較好地應對動態載入的問題,但也犧牲了抓取速度。
    • 資料儲存的結構設計和最佳化也是需要重點關注的部分,特別是在處理大規模資料時,要確保資料庫的高效查詢和資料的完整性。
    • 很多股票資料是透過JavaScript動態載入的,因此需要透過Selenium獲取頁面原始碼,或者直接分析API請求,找到資料來源。通常情況下,網站的資料以JSON形式返回,可以直接透過API介面進行獲取,避免使用Selenium來模擬瀏覽器。

    作業②

  • 要求

    • 熟練掌握 Selenium 查詢HTML元素、實現使用者模擬登入、爬取Ajax網頁資料、等待HTML元素等內容。
    • 使用Selenium框架+MySQL爬取中國mooc網課程資源資訊(課程號、課程名稱、學校名稱、主講教師、團隊成員、參加人數、課程進度、課程簡介)

程式碼如下

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ChromeService
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import pymysql

chrome_options = ChromeOptions()
chrome_options.add_argument('--disable-gpu')
chrome_options.binary_location = r'C:\Users\20733\AppData\Local\Google\Chrome\Application\chrome.exe'
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# chrome_options.add_argument('--headless')  # 無頭模式
service = ChromeService(executable_path='C:/Users/20733/AppData/Local/Programs/Python/Python313/Scripts/chromedriver.exe')
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.maximize_window()  # 使瀏覽器視窗最大化
# 連線MySql
try:
    db = pymysql.connect( host='127.0.0.1', user='root', passwd='Cjkmysql.', port=3306, charset='utf8',
        database='chenoojkk',)
    cursor = db.cursor()
    cursor.execute('DROP TABLE IF EXISTS courseMessage')
    sql = '''CREATE TABLE courseMessage(cCourse varchar(64),cCollege varchar(64),cTeacher varchar(16),cTeam varchar(256),cCount varchar(16),
    cProcess varchar(32),cBrief varchar(2048))'''
    cursor.execute(sql)
except Exception as e:
    print(e)


# 爬取一個頁面的資料
def spiderOnePage():
    time.sleep(5)  # 等待頁面載入完成
    courses = driver.find_elements(By.XPATH, '//*[@id="channel-course-list"]/div/div/div[2]/div[1]/div')
    current_window_handle = driver.current_window_handle
    for course in courses:
        cCourse = course.find_element(By.XPATH, './/h3').text  # 課程名
        cCollege = course.find_element(By.XPATH, './/p[@class="_2lZi3"]').text  # 大學名稱
        cTeacher = course.find_element(By.XPATH, './/div[@class="_1Zkj9"]').text  # 主講老師
        cCount = course.find_element(By.XPATH, './/div[@class="jvxcQ"]/span').text  # 參與該課程的人數
        cProcess = course.find_element(By.XPATH, './/div[@class="jvxcQ"]/div').text  # 課程進展

        course.click()  # 點選進入課程詳情頁,在新標籤頁中開啟
        Handles = driver.window_handles  # 獲取當前瀏覽器的所有頁面的控制代碼
        driver.switch_to.window(Handles[1])  # 跳轉到新標籤頁
        time.sleep(5)  # 等待頁面載入完成

        # 爬取課程詳情資料
        # cBrief = WebDriverWait(driver,10,0.48).until(EC.presence_of_element_located((By.ID,'j-rectxt2'))).text
        cBrief = driver.find_element(By.XPATH, '//*[@id="j-rectxt2"]').text
        if len(cBrief) == 0:
            cBriefs = driver.find_elements(By.XPATH, '//*[@id="content-section"]/div[4]/div//*')
            cBrief = ""
            for c in cBriefs:
                cBrief += c.text

        # 將文字中的引號進行轉義處理,防止插入表格時報錯
        cBrief = cBrief.replace('"', r'\"').replace("'", r"\'")
        cBrief = cBrief.strip()

        # 爬取老師團隊資訊
        nameList = []
        cTeachers = driver.find_elements(By.XPATH, '//div[@class="um-list-slider_con_item"]')
        for Teacher in cTeachers:
            name = Teacher.find_element(By.XPATH, './/h3[@class="f-fc3"]').text.strip()
            nameList.append(name)
        # 如果有下一頁的標籤,就點選它,然後繼續爬取
        nextButton = driver.find_elements(By.XPATH, '//div[@class="um-list-slider_next f-pa"]')
        while len(nextButton) != 0:
            nextButton[0].click()
            time.sleep(3)
            cTeachers = driver.find_elements(By.XPATH, '//div[@class="um-list-slider_con_item"]')
            for Teacher in cTeachers:
                name = Teacher.find_element(By.XPATH, './/h3[@class="f-fc3"]').text.strip()
                nameList.append(name)
            nextButton = driver.find_elements(By.XPATH, '//div[@class="um-list-slider_next f-pa"]')
        cTeam = ','.join(nameList)

        driver.close()  # 關閉新標籤頁
        driver.switch_to.window(current_window_handle)  # 跳轉回原始頁面
        try:
            cursor.execute('INSERT INTO courseMessage VALUES ("%s","%s","%s","%s","%s","%s","%s")' % (
            cCourse, cCollege, cTeacher, cTeam, cCount, cProcess, cBrief))
            db.commit()
        except Exception as e:
            print(e)
# 訪問中國大學慕課
driver.get('https://www.icourse163.org/')

# 訪問國家精品課程
driver.get(WebDriverWait(driver,15,0.48).until(EC.presence_of_element_located((By.XPATH,'//*[@id="app"]/div/div/div[1]/div[1]/div[1]/span[1]/a'))).get_attribute('href'))
spiderOnePage()  # 爬取第一頁的內容

count = 1
'''翻頁操作'''
# 下一頁的按鈕

next_page = driver.find_element(By.XPATH,'//*[@id="channel-course-list"]/div/div/div[2]/div[2]/div/a[10]')
# 如果還有下一頁,那麼該標籤的class屬性為_3YiUU
while next_page.get_attribute('class') == '_3YiUU ':
    if count == 5:
        break
    count += 1
    next_page.click()  # 點選按鈕實現翻頁
    spiderOnePage()  # 爬取一頁的內容
    next_page = driver.find_element(By.XPATH,'//*[@id="channel-course-list"]/div/div/div[2]/div[2]/div/a[10]')

try:
    cursor.close()
    db.close()
except:
    pass

time.sleep(3)
driver.quit()

輸出資訊:

Gitee資料夾連結:陳家凱第四次實踐作業

心得體會:

  • 元素定位方式的選擇:Selenium提供了多種方式來查詢頁面元素,例如 find_element_by_xpathfind_element_by_idfind_element_by_class_name 等。選擇合適的定位方式是保證爬蟲穩定性的關鍵。一般來說,XPath 更為靈活,適用於複雜的網頁結構,但效率較低;而 IDClass 定位效率較高,但有時網頁結構不規範,ID和Class可能變化頻繁。
  • 合理使用顯式和隱式等待:在抓取動態載入的網頁時,顯式等待(WebDriverWait 是非常重要的。由於MOOC網課程資訊的很多內容是透過JavaScript動態載入的,直接抓取頁面可能導致獲取到的內容為空或不完整。我使用了 WebDriverWait 等待特定元素載入完成後再進行抓取,確保資料的完整性和準確性。隱式等待(implicitly_wait)也有其用處,它會在查詢每個元素時等待一定時間,但顯式等待能更精確地控制等待時間。
  • 避免元素定位失敗:爬蟲中常見的一個問題是頁面結構的變化或載入錯誤導致元素定位失敗。我透過新增異常處理機制(如try-except)來捕獲定位失敗的情況,並根據實際情況進行重試或跳過錯誤元素。

作業③

  • 要求:

    • 掌握大資料相關服務,熟悉Xshell的使用

    • 完成文件 華為雲_大資料實時分析處理實驗手冊-Flume日誌採集實驗(部分)v2.docx 中的任務,即為下面5個任務,具體操作見文件。

  • 環境搭建:

    • 任務一:開通MapReduce服務
  • 實時分析開發實戰:

    • 任務一:Python指令碼生成測試資料


    • 任務二:配置Kafka





    • 任務三: 安裝Flume客戶端


    • 任務四:配置Flume採集資料

釋放資源:

Gitee資料夾連結:陳家凱第四次實踐作業

**心得體會:透過這個實驗,我還更加理解了實時資料採集和處理的複雜性。雖然Flume本身非常強大,但在實際生產環境中,我們需要結合業務需求,進行細緻的調優和監控。例如,如何處理高併發場景中的資料丟失問題,如何避免資料積壓等問題,這些都需要根據具體情況進行配置和調整。總的來說,透過此次實驗,我不僅學到了Flume的配置與應用技巧,更重要的是,我深刻體會到大資料處理過程中每一個環節的緊密配合。資料採集、儲存、分析的每一步都需要精心設計和最佳化,Flume作為資料採集的“前哨”,為後續的實時資料分析和處理奠定了堅實的基礎。這次實踐經驗無疑為我未來在大資料專案中的應用提供了寶貴的參考,特別是在日誌資料採集、流式資料處理等方面的能力提升,將讓我在未來的專案中更加得心應手。

相關文章