資料採集與融合技術_實踐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日誌採集的步驟。