馮成 劉昉
摘要:隨著計(jì)算機(jī)技術(shù)的發(fā)展,圖像數(shù)據(jù)被廣泛地應(yīng)用在各種領(lǐng)域。因此,圖像數(shù)據(jù)越來(lái)越受到人們重視。文章通過(guò)分析傳統(tǒng)網(wǎng)絡(luò)爬蟲(chóng)技術(shù)采集和數(shù)據(jù)存儲(chǔ),指出其受到各種因素限制,導(dǎo)致采集圖像數(shù)據(jù)的效率低下,代碼設(shè)計(jì)編寫(xiě)工作復(fù)雜,且容易造成存儲(chǔ)資源的浪費(fèi)。為了進(jìn)一步提高網(wǎng)絡(luò)爬蟲(chóng)效率,簡(jiǎn)化圖像采集的實(shí)現(xiàn)過(guò)程以及節(jié)約磁盤(pán)的存儲(chǔ)空間。文章以汽車(chē)之家為案例,使用一種基于Selenium+WebDriver方式完成對(duì)汽車(chē)圖像數(shù)據(jù)自動(dòng)化采集,并通過(guò)OpenCV算法將汽車(chē)圖像數(shù)據(jù)進(jìn)行大比例壓縮,較大地節(jié)約磁盤(pán)的存儲(chǔ)空間。
關(guān)鍵詞:圖像數(shù)據(jù);自動(dòng)采集;存儲(chǔ);壓縮
中圖分類(lèi)號(hào):TN919.1
文獻(xiàn)標(biāo)志碼:A
0 引言
隨著社會(huì)經(jīng)濟(jì)的快速發(fā)展,汽車(chē)已經(jīng)進(jìn)入千家萬(wàn)戶。在互聯(lián)網(wǎng)中的各類(lèi)主題網(wǎng)站中存在海量的各類(lèi)汽車(chē)圖像,這些汽車(chē)圖像廣受人們的喜愛(ài)。受制于技術(shù),大多數(shù)普通用戶無(wú)法使用自動(dòng)化的方式下載自己喜歡的圖像。因此,為了解決這一問(wèn)題,本文采用Selenium+WebDriver自動(dòng)化方式采集汽車(chē)之家的圖像數(shù)據(jù),使用網(wǎng)絡(luò)爬蟲(chóng)庫(kù)Xpath完成數(shù)據(jù)的解析以及采集之后汽車(chē)圖像命名,并用OpenCV技術(shù)將汽車(chē)圖像數(shù)據(jù)下載和壓縮至本地。
1 相關(guān)技術(shù)的介紹
近年來(lái),隨著互聯(lián)網(wǎng)技術(shù)的快速發(fā)展[1],互聯(lián)網(wǎng)技術(shù)在豐富網(wǎng)站頁(yè)面元素同時(shí),也促進(jìn)了網(wǎng)絡(luò)爬蟲(chóng)技術(shù)快速的提升。網(wǎng)站頁(yè)面逐漸由單一式的靜態(tài)網(wǎng)頁(yè)界面逐步發(fā)展為頁(yè)面元素豐富的動(dòng)態(tài)交互式網(wǎng)頁(yè)。網(wǎng)絡(luò)爬蟲(chóng)中數(shù)據(jù)抓取的方式也由支持靜態(tài)網(wǎng)頁(yè)抓取的urllib、urllib3、requests庫(kù),發(fā)展到支持?jǐn)?shù)據(jù)動(dòng)態(tài)獲取Selenium庫(kù)和大型項(xiàng)目scrapy框架。
requests是數(shù)據(jù)請(qǐng)求庫(kù),用戶使用requests庫(kù)支持的get或者post方法發(fā)送對(duì)靜態(tài)網(wǎng)頁(yè)的請(qǐng)求,其中g(shù)et方法主要應(yīng)用于普通網(wǎng)址的請(qǐng)求,post方法主要應(yīng)用于攜帶表單數(shù)據(jù)的請(qǐng)求,通過(guò)上述兩種方法,能夠獲取請(qǐng)求網(wǎng)頁(yè)的源代碼。
Xpath(XML Path Language)是一款常用的數(shù)據(jù)解析庫(kù),用戶可以根據(jù)頁(yè)面元素位置,描述頁(yè)面路徑表達(dá)式。用戶可以使用xpath()方法提取相應(yīng)的數(shù)據(jù)。
Selenium是一個(gè)廣泛應(yīng)用于軟件測(cè)試領(lǐng)域的工具[2]。Selenium庫(kù)具有開(kāi)源性,而被應(yīng)用在Python網(wǎng)絡(luò)爬蟲(chóng)上。其本質(zhì)上模擬人操作指定的瀏覽器,并實(shí)現(xiàn)在瀏覽器頁(yè)面上按鈕點(diǎn)擊、頁(yè)面元素的定位、頁(yè)面的選擇、鍵盤(pán)的輸入等操作,實(shí)現(xiàn)瀏覽即可完成數(shù)據(jù)的抓取。
Selenium支持多款常用瀏覽器。在本文中,Selenium可以結(jié)合ChromeDriver使用。用戶安裝ChromeDriver根據(jù)Google Chrome當(dāng)前的版本號(hào),選擇相應(yīng)的ChromeDriver版本,并在系統(tǒng)環(huán)境變量中配置Path路徑即可使用。
圖像壓縮一直是圖形圖像領(lǐng)域中比較熱門(mén)的研究方向,主要的圖像壓縮工作可以選擇在“變換”“量化”“編碼”過(guò)程中完成。壓縮分類(lèi)又可分為有損壓縮和無(wú)損壓縮,有損壓縮是具有高壓縮比且允許圖像失真的一種壓縮方法,廣泛應(yīng)用于圖形圖像、視頻、音頻數(shù)據(jù)的壓縮等方面。
OpenCV是一款開(kāi)源且支持多種編程語(yǔ)言的跨平臺(tái)計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)庫(kù)[3]。OpenCV-Python為OpenCV的接口,它提供了全面豐富且易用的圖形圖像處理函數(shù),因此被廣泛地應(yīng)用在圖形圖像領(lǐng)域。
2 圖像數(shù)據(jù)的抓取
基于Selenium+WebDriver汽車(chē)之家自動(dòng)化爬取汽車(chē)圖像數(shù)據(jù),大致的流程如下:
(1) 第三方庫(kù)的安裝。
(2) 發(fā)送主頁(yè)網(wǎng)址請(qǐng)求,輸入搜索關(guān)鍵字完成關(guān)鍵字的搜索,實(shí)現(xiàn)網(wǎng)頁(yè)的跳轉(zhuǎn)和網(wǎng)頁(yè)頁(yè)面的切換操作。
(3) 針對(duì)多頁(yè)汽車(chē)圖像網(wǎng)頁(yè),實(shí)現(xiàn)汽車(chē)圖像網(wǎng)頁(yè)的分頁(yè)跳轉(zhuǎn)操作。
(4) 針對(duì)汽車(chē)圖像數(shù)據(jù)對(duì)圖像進(jìn)行下載。
(5) 針對(duì)下載后的圖像進(jìn)行壓縮和存儲(chǔ)。
2.1 第三方庫(kù)的安裝
本文是在PyCharm環(huán)境下完成項(xiàng)目的開(kāi)發(fā),在程序編寫(xiě)前需要使用pip命令行的方式安裝requests、lxml庫(kù)和Selenium庫(kù)、OpenCV-Python庫(kù),具體安裝方式如表1所示。
2.2 數(shù)據(jù)請(qǐng)求
2.2.1 請(qǐng)求配置
通過(guò)谷歌瀏覽器訪問(wèn)“汽車(chē)之家”首頁(yè)并復(fù)制其網(wǎng)址。在py文件中從Selenium模塊中導(dǎo)入WebDriver庫(kù),關(guān)鍵代碼為:“from Selenium import WebDriver”,為了方便針對(duì)爬取頁(yè)面的數(shù)據(jù)定位和分析,需要將瀏覽器設(shè)置成為不自動(dòng)關(guān)閉的狀態(tài),其關(guān)鍵代碼如下:opt.add_experimental_option(‘detach,True),同時(shí)使用 opt.page_load_strategy = ‘eager配置內(nèi)容,下載html內(nèi)容,解決了自動(dòng)化采集數(shù)據(jù)緩慢的問(wèn)題,較大地改善網(wǎng)頁(yè)爬蟲(chóng)速度。使用WebDriver.Chrome(opt)方法,opt為配置內(nèi)容,生成Chrome對(duì)象。利用該對(duì)象使用get方法發(fā)送針對(duì)“汽車(chē)之家”的請(qǐng)求,其關(guān)鍵代碼如: driver.get(url=‘https://www.autohome.com.cn/qiandongnan/)。由于首次訪問(wèn)主頁(yè),網(wǎng)站自動(dòng)彈出廣告,需要使用time.sleep(nums)方法暫停程序執(zhí)行,nums為秒數(shù),等待廣告自動(dòng)結(jié)束彈框自動(dòng)消失,能夠有效地解決彈窗廣告導(dǎo)致的網(wǎng)站頁(yè)面不一致的問(wèn)題。
2.2.2 數(shù)據(jù)的發(fā)送和詳情頁(yè)進(jìn)入
獲取Selenium對(duì)象后,需要選擇合適的方式定位搜索框。目前,Selenium庫(kù)支持的find_element含有XPATH,ID,NAME,CLASS_NAME,LINK_TEXT,PARTIAL_LINK_TEXT,TAG_NAME等多種定位頁(yè)面元素方式。本文根據(jù)分析首頁(yè)頁(yè)面元素情況,選擇使用ID和CLASS_NAME定位搜索框和搜索按鈕,并使用send_keys(“搜索關(guān)鍵詞”)方法實(shí)現(xiàn)搜索框數(shù)據(jù)的填充,通過(guò)調(diào)用click()方法模擬鼠標(biāo)的點(diǎn)擊,其核心代碼如下:
driver.find_element(by=By.ID,value=q).send_keys("關(guān)鍵詞")
driver.find_element(by=By.CLASS_NAME,value=‘btn-search).click()
等待頁(yè)面跳轉(zhuǎn)完成之后,需要將程序切換至新的網(wǎng)頁(yè)頁(yè)面中,使用WebDriver提供switch_to.window(driver.window_handles[-1])方法完成最后頁(yè)面的切換,同時(shí)需要程序多次使用定位、點(diǎn)擊、頁(yè)面切換等方法進(jìn)入至汽車(chē)詳情頁(yè)。
3 分頁(yè)跳轉(zhuǎn)
由于汽車(chē)圖像數(shù)據(jù)存在多個(gè)頁(yè)面之中,因此需要采用分頁(yè)的方式完成數(shù)據(jù)的采集。本文利用Python循環(huán)的方法,完成汽車(chē)圖像數(shù)據(jù)的翻頁(yè)操作。本研究定義了“死循環(huán)”,當(dāng)使用link_text方法定位到“下一頁(yè)”,利用get_attribute(“class”)方法獲取屬性值,與其屬性值進(jìn)行比較。如果不滿足選擇判斷條件,則對(duì)“下一頁(yè)”進(jìn)行點(diǎn)擊,并切換到最后一個(gè)頁(yè)面并使用driver.current_url方法獲取當(dāng)前頁(yè)面的url地址,將url地址轉(zhuǎn)發(fā)至數(shù)據(jù)下載模塊中。否則,若判斷的是最后一頁(yè),則采用break的方法結(jié)束循環(huán)。其核心代碼如下:
……
while True:#若當(dāng)前頁(yè)面不是最后一頁(yè),則完成程序的跳轉(zhuǎn)。
if driver.find_element(by=By.LINK_TEXT,value=‘下一頁(yè)).get_attribute(‘class)!=‘page-item-next page-disabled:
driver.find_element(by=By.LINK_TEXT,value=‘下一頁(yè)).click()
driver.switch_to.window(driver.window_handles[-1])
d_url=driver.current_url
download(d_url)
else: #若當(dāng)前頁(yè)面是最后一頁(yè),則停止程序
break
…………
4 圖像數(shù)據(jù)下載
在圖像下載模塊中,獲取download(d_url)參數(shù)傳遞過(guò)來(lái)的每一頁(yè)汽車(chē)圖像網(wǎng)址之后,對(duì)該網(wǎng)址數(shù)據(jù)使用requests.get(url=d_url,headers=headers)發(fā)送請(qǐng)求,url為請(qǐng)求網(wǎng)址參數(shù),headers為包含著鍵值對(duì)的字典類(lèi)型請(qǐng)求標(biāo)頭數(shù)據(jù),主要應(yīng)對(duì)網(wǎng)站的爬蟲(chóng)措施。等待服務(wù)器頁(yè)面響應(yīng)。觀察和分析響應(yīng)網(wǎng)頁(yè)頁(yè)面元素發(fā)現(xiàn),多張汽車(chē)圖像數(shù)據(jù)都在同一個(gè)ul標(biāo)簽下,通過(guò)xpath完成數(shù)據(jù)的解析,獲取含有所有汽車(chē)圖像的ul標(biāo)簽內(nèi)容。其核心代碼如下:pic_list = html.xpath(‘/html/body/div[2]/div/div[2]/div[7]/div/div[2]/div[2]/ul),通過(guò)使用循環(huán)xpath返回的列表內(nèi)容,獲取當(dāng)前標(biāo)簽下的每一個(gè)li標(biāo)簽的src汽車(chē)圖像具體網(wǎng)址的屬性值。
for pic in pic_list:#./表示當(dāng)前目錄,@src表示獲取src屬性的值
pic_url = pic.xpath(‘./li/a/img/@src)
再次循環(huán)pic_url提取每一個(gè)汽車(chē)圖像的具體網(wǎng)絡(luò)地址,將提取到的網(wǎng)址進(jìn)行拼接。url_new = ‘https: + pic_url_a。針對(duì)拼接后的網(wǎng)址,再次發(fā)送requests請(qǐng)求,其代碼如下:response=request.get(url=url_new,headers=headers),等待頁(yè)面數(shù)據(jù)的響應(yīng)之后,獲取汽車(chē)圖像二進(jìn)制數(shù)據(jù),并使用with open(pic_url_name,‘wb)as f的方法完成數(shù)據(jù)的寫(xiě)入,Pic_url_name為汽車(chē)名稱(chēng),汽車(chē)名稱(chēng)截取于圖像數(shù)據(jù)的鏈接地址最后一個(gè)索引所對(duì)應(yīng)的數(shù)據(jù),保持汽車(chē)名稱(chēng)數(shù)據(jù)的唯一性。pic_url_name = pic_url_a.split(‘__)[-1]。‘wb為二進(jìn)制方式寫(xiě)入數(shù)據(jù)。將汽車(chē)圖像數(shù)據(jù)寫(xiě)入文件。f.writer(response.content)。
5 圖像數(shù)據(jù)壓縮
面對(duì)大量圖像數(shù)據(jù)的存儲(chǔ),往往受限于單機(jī)存儲(chǔ)空間的容量。為了節(jié)約存儲(chǔ)空間,本研究使用OpenCV庫(kù)完成圖像壓縮。
首先,自定義圖片壓縮方法:
picture_compress(i_file,o_file,target_size,quality,step,pic_type)
其中,i_file:文件的輸入路徑。
o_file:文件的輸出路徑。
Target_size:輸出文件的大小,設(shè)置該值為60。
Quality:初始?jí)嚎s比,數(shù)值越高,圖片的質(zhì)量越好,設(shè)置該值為80。
Step:調(diào)整壓縮比,設(shè)置該值為10。
pic_type:圖片的格式,設(shè)置該值為jpg。
其次,通過(guò)read()方法,讀取圖像字節(jié)數(shù)據(jù),并將數(shù)據(jù)放入buffer中,等待cv對(duì)象從內(nèi)存緩存中讀取任何顏色格式圖像數(shù)據(jù)。img_cv2=cv2.imdecode(bufferdata,cv2.ImREAD_ANYCOLOR)。
使用循環(huán)方式判斷當(dāng)前圖像容量是否大于設(shè)定的目標(biāo)值,如果當(dāng)前圖像容量大于目標(biāo)容量,則繼續(xù)按照jpg圖片格式編碼,并設(shè)置圖像初始?jí)嚎s比quality,進(jìn)行圖像數(shù)據(jù)的壓縮。cv2.imencode(‘.jpg,img_cv2,[int(cv2,IMWRITER_JPEG_QUALITY),quality])[1]。
最后,使用with open(o_file,‘rb)方式寫(xiě)入數(shù)據(jù),生成新的文件。通過(guò)完成上述步驟將源文件分辨率為480×360、容量為86.5 KB的圖像,壓縮成分辨率為480×360、容量為37.5 KB、壓縮比約為56%的圖像,圖像效果較好。壓縮前后對(duì)比如圖1所示。
6 結(jié)語(yǔ)
本文主要采用自動(dòng)化方式對(duì)汽車(chē)之家的指定汽車(chē)圖像數(shù)據(jù)進(jìn)行爬取,并利用OpenCV算法將下載圖像壓縮,并保存到本地,達(dá)到了預(yù)期效果,為“網(wǎng)絡(luò)爬蟲(chóng)技術(shù)”課程的教學(xué)活動(dòng)開(kāi)展,積累了豐富的實(shí)踐應(yīng)用案例。
參考文獻(xiàn)
[1]劉相平.大數(shù)據(jù)環(huán)境下Hadoop作業(yè)調(diào)度算法研究[D].成都:電子科技大學(xué),2015.
[2]閆龍川,張冰,袁孝宇,等.電力信息系統(tǒng)業(yè)務(wù)自動(dòng)測(cè)試驗(yàn)證系統(tǒng)設(shè)計(jì)與應(yīng)用[J].電力信息與通信技術(shù),2022(2):63-68.
[3]曹瀚仁,葛其運(yùn),王鑫.用于手車(chē)式中壓斷路器限位開(kāi)關(guān)的視頻檢測(cè)控制系統(tǒng)軟件設(shè)計(jì)與實(shí)現(xiàn)[J].現(xiàn)代電子技術(shù),2022(24):86-91.
(編輯 王永超)
Based on automated image data acquisition by Selenium
Feng Cheng, Liu Fang
(Guizhou Electronic Information Vocational and Technical College, Kaili 556000, China)
Abstract: With the development of computer technology, image data is widely used in various fields, so image data is getting more and more attention. By analyzing the traditional web crawler technology collection and data storage, this paper points out that it is limited by various factors, leading to the low efficiency of image data collection, complex code design and writing work, and easy to cause the waste of storage resources. In order to further improve the efficiency of the web crawler, simplify the implementation process of image acquisition and save the disk storage space, this paper takes Autohome as an example, using a Selenium + WebDriver method to complete the automatic collection of automobile image data, and compress the car image data in a large proportion through OpenCV algorithm, so as to save the storage space of the disk.
Key words: image data; automatic collection; storage; compression