資料採集實驗四

Yx114514發表於2024-11-12

作業一

(1)實驗內容

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

gitee倉庫連結:作業4

完整程式碼如下

highlighter- apache

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:\Program Files\Google\Chrome\Application\chrome.exe'
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
service = ChromeService(executable_path='E:/FZU/sjcj/10.21/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',password='040417',port=3306,database='scrapy')
    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()

navicat檢視結果

(2)心得體會

  • 使用selenium庫可以爬取動態載入的資料,編寫xpath表示式時要注意相對路徑的使用,最開始沒注意,剛好表又定義了主鍵,將資料插入表格時就報了主鍵重複的錯誤

  • 不同欄位本來想定義不同的資料型別,比如double,但是後來發現爬取下來的資料格式不一定統一,比如成交量這列資料,有的資料帶了單位萬,有的又沒帶,最終決定統一將欄位資料型別定義為字串,如果想定義不同資料型別,需對爬取下來的資料進一步處理

  • 由於要爬取的資料是動態載入的,所以需要強制等待一段時間,等待資料載入完成,才能開始爬取,否則會出現找不到標籤的情況,最開始嘗試使用WebDriverWait類進行等待,貌似行不通,最後改成使用sleep()函式進行等待

    highlighter- reasonml

    # 爬取一個頁面的資料
    def spiderOnePage():
        time.sleep(3)
        trs = driver.find_elements(By.XPATH,'//table[@id="table_wrapper-table"]//tr[@class]')
    

作業二

(1)實驗內容

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

gitee倉庫連結:作業4

完整程式碼如下

highlighter- python

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:\Program Files\Google\Chrome\Application\chrome.exe'
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# chrome_options.add_argument('--headless')  # 無頭模式
service = ChromeService(executable_path='E:/FZU/sjcj/10.21/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',password='040417',port=3306,database='scrapy')
    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/')

# 點選登入按鈕
# WebDriverWait(driver,10,0.48).until(EC.presence_of_element_located((By.XPATH,'//a[@class="f-f0 navLoginBtn"]'))).click()
# iframe = WebDriverWait(driver,10,0.48).until(EC.presence_of_element_located((By.XPATH,'//*[@frameborder="0"]')))
# 轉到登入介面的iframe
# driver.switch_to.frame(iframe)
# 輸入賬號密碼並點選登入按鈕
# driver.find_element(By.XPATH,'//*[@id="phoneipt"]').send_keys("17850751681")
# time.sleep(2)
# driver.find_element(By.XPATH,'//*[@class="j-inputtext dlemail"]').send_keys("yx040417@")
# time.sleep(2)
# driver.find_element(By.ID,'submitBtn').click()


# 訪問國家精品課程
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()

navicat檢視結果

(2)心得體會

  • 模擬登入時,輸入框以及登入按鈕的標籤都位於iframe標籤中,需要使用switch_to.frame()函式將查詢區域變更為對應iframe,才能找到輸入框以及登入按鈕。每個iframe一般都有唯一的ID屬性,但是該網站的ID屬性值是動態生成的,每次載入的ID都不一樣,最終選擇根據frameborder屬性值來定位該iframe。在嘗試過程中發現,多次模擬登入後,再次登入會跳出滑塊驗證。

  • 但是!!!每次登入後的彈窗影響爬蟲爬取XPath,一開始嘗試寫一個程式點選同意以解決該問題,可惜沒有成功,一怒之下索性不登陸爬取,發現可以進行。

  • 我選擇點選進入國家精品,爬取該網頁下的課程。該頁面下只包含部分資料,課程介紹,教師團隊等資訊還需要進入具體的課程網頁進行爬取,由於沒有在標籤中找到具體課程頁面的url,於是採用點選的方式進入,且點選之後,是在新標籤頁中開啟該網頁,這就需要進行標籤頁的切換,使用switch_to.window()函式可以實現標籤頁的切換,使用close()函式可以關閉標籤頁

  • 爬取教師團隊資訊時,當團隊人數較多時,該網頁並沒有將所有老師一次性列出,需要進行區域性翻頁處理。與國家精品課程頁面的翻頁操作不同,當沒有下一頁時,下一頁這個標籤直接消失,而不是class屬性值發生變化。可以改用find_elements查詢該標籤,如果沒找到,只是返回空列表,並不會像find_element一樣產生異常。

作業三

(1)實驗內容

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





















相關文章