1. 程式人生 > 其它 >資料採集與融合技術_實踐5

資料採集與融合技術_實踐5

作業①:

要求
熟練掌握 Selenium 查詢HTML元素、爬取Ajax網頁資料、等待HTML元素等內容。
使用Selenium框架爬取京東商城某類商品資訊及圖片。
候選網站:http://www.jd.com/
關鍵詞:學生自由選擇

1.1 實驗過程

1.1.1 模擬使用者搜尋商品關鍵詞

  • 在京東的主頁面上對搜尋欄點選右鍵進行檢查,通過 find_element_by_id("key") 進行定位,
    模擬使用者填寫搜尋關鍵詞並回車進入相關頁面。
self.driver.get(url) #JD首頁
keyInput = self.driver.find_element_by_id("key") #尋找搜尋欄
keyInput.send_keys(key)#將關鍵詞手機輸入
keyInput.send_keys(Keys.ENTER) #模擬回車

send_keys 的一些用法:剪下貼上全選等操作與複製相似,修改為對應字母即可。

語法 效果
send_keys(Keys.BACK_SPACE) 刪除鍵BackSpace
send_keys(Keys.SPACE) 空格鍵Space
send_keys(Keys.ENTER) 回車鍵Enter
send_keys(Keys.CONTROL,‘c’) 複製CTRL+C

1.1.2 爬取商品資訊

  • 關於 mMark 的獲取:
    觀察發現,標題的第一個單詞即為手機的品牌,所以我們需要對標題進行分割。
    但是要注意有些手機品牌前面會存在“京品手機”的標籤,我們需要將其刪除。
  • 通過空格進行切割後可以發現,京品手機是和品牌連在一起的,所以可得程式碼如下:
note = li.find_element_by_xpath(".//div[@class='p-name p-name-type-2']//em").text
mark = note.split(" ")[0]
if(mark[0:4] == '京品手機'):  #去除不必要的資訊
    mark = mark[4:]
  • 關於圖片src的獲取:
    需要分以下兩種情況
Xpath路徑
li.find_element_by_xpath(".//div[@class='p-img']//a//img").get_attribute("src")
li.find_element_by_xpath(".//div[@class='p-img']//a//img").get_attribute("data-lazy-img")

我比較疑惑的是屬性 data-lazy-img,因為直接檢視網頁html或使用xpath helper時,這個屬性的值都是done,並且圖片的地址都是在 src 屬性中。

查詢相關資料發現,我所看到的html是經過響應的,使用python獲取原始碼就可以明白其中緣由。

  • 其他資訊正常獲取即可,根據需要可以做一些處理,這裡就不再展示。

1.1.3 商品載入

  • 可以發現,頁面下拉前每頁只有 30 件商品
  • 然而,頁面下拉後每頁共有 60 件商品
  • 因此如果要獲取完整資訊,需要使用模擬下拉的方式載入更多的商品。
    而滾動條是無法直接定位的。selenium中也沒有直接的方法來控制滾動條,我們可以用Js處理。
#控制頁面下拉
js = 'document.documentElement.scrollTop=10000' #10000代表底部
self.driver.execute_script(js)
time.sleep(5) #需要停止一段時間,讓頁面載入

1.1.4 翻頁處理

  • 限制爬取的數量為101,由於每頁有60件商品,所以只會爬到第二頁。
if(self.No < 101): #限定爬取101個
    try:
        nextPage = self.driver.find_element_by_xpath("//span[@class='p-num']//a[@class='pn-next']")
        time.sleep(5)
        nextPage.click()
        self.processSpider() #爬取新的一頁
    except Exception as err:
        print(err)

1.1.5 下載圖片

  • urllib請求訪問資源,獲取圖片資料,注意一下傳過來的src1和src2是 相對地址,需要先使用urljoin進行補全,才能正確訪問。
    成功下載後,儲存到本地資料夾。
    #urllib請求
    req = urllib.request.Request(src1, headers=MySpider.headers)
    resp = urllib.request.urlopen(req, timeout=10)
    data = resp.read()
    ...
if data:  #成功獲取圖片資料後才需要寫入
    fobj = open(MySpider.imagePath + "\\" + mFile, "wb")
    fobj.write(data)
    fobj.close()

1.1.6 資料庫

  • 建表
def openDB(self):
    print("opened")
    try:
        #資料庫連線
        self.con = pymysql.connect(host="localhost", port=3306, user="root",
                                   passwd="cccc", db="crawl", charset="utf8")
        self.cursor = self.con.cursor(pymysql.cursors.DictCursor)
        #建立表
        sql = "create  table  phones  (mNo  varchar(32) primary key, mMark varchar(256)," \
              "mPrice varchar(32),mNote varchar(1024),mFile varchar(256))"
        self.cursor.execute(sql)
    #如果已經存在,則刪除資料
    except Exception as err:
        self.cursor.execute("delete from phones")
  • 插入
def insert(self,mNo, mMark, mPrice, mNote, mFile):
    #if self.opened:
    sql = "insert into phones (mNo,mMark,mPrice,mNote,mFile) values ( % s, % s, % s, % s, % s)"
    self.cursor.execute(sql, (mNo, mMark, mPrice, mNote, mFile))

1.1.7 執行結果

  • 資料庫儲存
  • 下載的圖片

1.2 實驗心得

  • 本題主要是利用Selenium模擬爬取京東的商品存入資料庫,並下載相關圖片。
    新學了通過執行js指令碼進行頁面下拉的方式,但是要記得sleep一段時間讓頁面載入。強化相對地址絕對地址的意識,要多多注意。

程式碼連結

https://gitee.com/yozhibo/crawl_project/blob/master/task_5/job_1

作業②:

要求
熟練掌握 Selenium 查詢HTML元素、實現使用者模擬登入、爬取Ajax網頁資料、等待HTML元素等內容。
使用Selenium框架+MySQL模擬登入慕課網,並獲取學生自己賬戶中已學課程的資訊儲存到MySQL中(課程號、課程名稱、授課單位、教學進度、課程狀態,課程圖片地址),同時儲存圖片到本地專案根目錄下的imgs資料夾中,圖片的名稱用課程名來儲存。
候選網站:中國mooc網:https://www.icourse163.org

2.1 實驗過程

2.1.1 模擬登陸

  • 兩種登入方法
    一是手機號登入,需要模擬更多的點選和輸入,而且會遇到巢狀頁面的問題,但完成後不需要每次執行都掃碼。
    二是掃碼登陸,需要設定幾秒的等待時間,用手機app掃碼登入。
  • 手機號登入:

① 模擬點選“登入”、“其他方式登入” 和 “手機號登入”

#登入入口
wait.until(EC.element_to_be_clickable(
    (By.XPATH, '//*[@id="app"]/div/div/div[1]/div[3]/div[3]/div'))).click()
#其他登入方式
wait.until(EC.element_to_be_clickable(
    (By.XPATH, '//div[@class="mooc-login-set"]//span[@class="ux-login-set-scan-code_ft_back"]'))).click()
#手機號登入
wait.until(EC.element_to_be_clickable(
    (By.XPATH, '//ul[@class="ux-tabs-underline_hd"]/li[position()=2]'))).click()

② 找到 iframe 並進行定位,並切換定位器到 iframe

#尋找巢狀的頁面
iframe = self.driver.find_element_by_xpath('//div[@id="j-ursContainer-1"]/iframe[1]')
self.driver.switch_to.frame(iframe)

②模擬輸入賬戶、密碼,點選登入

#賬號密碼
PHONENUM= "101" #在101行,可自行修改。
PASSWORD = "102"
#輸入賬戶
self.driver.find_element_by_xpath\
    ('//div[@class="u-input box"]//input[@type="tel"]').send_keys(PHONENUM)
#輸入密碼
self.driver.find_element_by_xpath\
    ('//div[@class="inputbox"]//input[@type="password"][2]').send_keys(PASSWORD)
#點選登入按鈕
self.driver.find_element_by_xpath('//*[@id="submitBtn"]').click()

  • 掃碼登入:
wait = WebDriverWait(self.driver, 8)
#登入入口
wait.until(EC.element_to_be_clickable(
    (By.XPATH, '//*[@id="app"]/div/div/div[1]/div[3]/div[3]/div'))).click()
#等待5秒,加上下一步會有 wait 8秒,掃碼時間還是比較充裕的
time.sleep(5)

2.1.2 課程資訊爬取

  • 首先要進入 “個人中心” 頁面
#點選個人中心
wait.until(EC.element_to_be_clickable(
    (By.XPATH,'//*[@id="j-indexNav-bar"]/div/div/div/div/div[7]/div[3]/div/div/a/span'))).click()

   進入後可以檢視各門課程:課程資訊在如圖框出來的部分,共6門。

  • 課程資訊的爬取比較常規,這裡直接展示主要程式碼
Id = self.No #序號
cCourse = li.find_element_by_xpath('.//span[@class="text"]').text   #課程名
cCollege = li.find_element_by_xpath('.//div[@class="school"]').text #開課大學
cSchedule = li.find_element_by_xpath('.//span[@class="course-progress-text-span"]').text #課程進度
cCourseStatus = li.find_element_by_xpath('.//div[@class="course-status"]').text  #課程狀態
cImgUrl = li.find_element_by_xpath('.//div[@class="img"]/img').get_attribute("src") #課程圖
self.No += 1

2.1.3 資料庫show()函式

  • 將爬取到的課程資訊輸出到控制檯
for row in rows:
    print("%-10s %-20s %-20s %-20s %-30s %-30s" % (row['Id'], row['cCourse'],
            row['cSchedule'], row['cSchedule'], row['cCourseStatus'],row['cImgUrl']))

2.1.4 圖片下載

  • 用課程名命名圖片,要注意補上圖片的格式。
p = cImgUrl.rfind(".")  #確定圖片字尾名位置
cCourse = cCourse + cImgUrl[p:p+4] #將圖片的字尾名加到課程名後
T = threading.Thread(target=self.download, args=(cImgUrl, cCourse)) #多執行緒下載

2.1.5 結果展示

  • 資料庫儲存
  • 資料庫輸出
  • 圖片下載

2.2 實驗心得

  • 除了因為渲染而無法正確定位外,還有可能是因為進行了頁面巢狀。
    掃碼登入時讓我對selenium有了更深的體會,它是用程式去模擬人的操作,
    而在這期間人也是可以有自己的操作,兩者結合可以相互彌補缺陷。

程式碼連結

  • 程式碼執行前需要 修改賬號密碼(位於101行和102行)

https://gitee.com/yozhibo/crawl_project/blob/master/task_5/job_2#

作業③:Flume日誌採集實驗

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

任務一:開通MapReduce服務(環境搭建)

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

  • 將本地的autodatapython.py檔案上傳至伺服器/opt/client/目錄下
  • 最終檢視資料:more /tmp/flume_spooldir/test.txt

任務三:配置Kafka

  • source環境變數
  • 在kafka中建立topic
  • 檢視topic資訊

任務四:安裝Flume客戶端

  • 解壓安裝包
  • 安裝Flume客戶端
  • 重啟Flume服務

任務五:配置Flume採集資料

  • 修改配置檔案後,用Xshell上傳到伺服器
  • 建立消費者消費kafka中的資料
  • 新開Xshell 7視窗,執行Python指令碼命令

實驗心得

  • 大體上還是跟著實驗步驟走,比較流暢。學會了在華為雲平臺上進行資源申請和釋放,特別是mapreduce服務,同時也初步掌握了flume日誌採集的步驟。