孫澤龍
(西安職業(yè)技術(shù)學(xué)院,陜西西安,710077)
由于現(xiàn)在絕大多數(shù)圖書網(wǎng)站都是基于一定的模板開發(fā)的,使用相關(guān)的模板,可以快速完成相同版式且不同內(nèi)容的大量頁面,通過這個規(guī)律只要把相同的內(nèi)容都獲取下來,求同存異地獲取實(shí)現(xiàn)大量頁面的目的[1]。
Python實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲需要手動安裝第三方庫。Python爬蟲需要HTTP請求,它可以理解為是從客戶端到服務(wù)器端的請求消息。即就是說,無論是真正的一個人在操作瀏覽器還是一個爬蟲,當(dāng)希望從服務(wù)器請求信息或服務(wù)時,首先就需要向服務(wù)器端發(fā)出一個請求,進(jìn)而服務(wù)器會返回相應(yīng)響應(yīng),最后連接關(guān)閉,Web服務(wù)的流程就是這樣完成的。本文用到的庫函數(shù)包含requests庫,使用requests庫調(diào)用get()和set()兩種提交方法獲取圖書網(wǎng)站源碼,如果網(wǎng)址需要提交的內(nèi)容是JSON格式,要進(jìn)行調(diào)用修改post()方法的一些參數(shù)。編碼格式用很多種,通過相關(guān)圖書網(wǎng)站編碼的測試,大多數(shù)情況下使用”utf-8”可以進(jìn)行中文正常顯示。單網(wǎng)絡(luò)爬蟲是只有一個線程和進(jìn)程,每次爬取訪問一個頁面,為了提高爬取效率和充分使用計(jì)算機(jī)網(wǎng)絡(luò)帶寬,一次同時讓爬蟲訪問多個頁面的目的,將使用多進(jìn)程技術(shù),通過調(diào)用multiprocessing多進(jìn)程庫,處理多進(jìn)程的相關(guān)操作。因?yàn)榕老x屬于讀寫操作密集型的事情,當(dāng)我們訪問請求網(wǎng)頁相關(guān)源碼時,多線程省去了大量等待返回網(wǎng)頁的時間[2]。當(dāng)然,對于訪問數(shù)量達(dá)到一定數(shù)量級時,多線程需要通過異步操作來保持自身爬蟲運(yùn)行的效率。
查看圖書網(wǎng)的網(wǎng)頁源碼后可以看出,它是一種結(jié)構(gòu)化的數(shù)據(jù),通過分析網(wǎng)頁結(jié)構(gòu)信息,Python的第三方庫BeautifulSoup4,可以用來提取HTML和XML頁面結(jié)構(gòu)內(nèi)容,一般需要處理解析源代碼從而生成BeautifulSoup對象,找到包含特殊屬性的標(biāo)簽,使用find()方法完成查找內(nèi)容。Python對文本文件操作中,可以導(dǎo)入CSV模塊完成對CSV文件的讀取,而且CSV文件用Excel應(yīng)用打開時可讀性高[3]。
解析器重要的功能是完成過濾選取網(wǎng)絡(luò)信息的作用。選取解析器的優(yōu)劣直接決定了網(wǎng)絡(luò)爬蟲的執(zhí)行速度和效率。Beautiful Soup不僅支持Python標(biāo)準(zhǔn)庫中的HTML解析器外,還支持一些第三方如lxml HTML、lxml XML、html5lib的解析器。Beautiful Soup的解析器對比如表1所示,列出了其目前主要的解析器,以及它們各自的優(yōu)缺點(diǎn)。
表1 BeautifulSoup解析器對比
本文以圖書網(wǎng)為案例來說明,爬取目標(biāo)內(nèi)容為圖書的名稱、價格及對應(yīng)圖書預(yù)覽圖的鏈接,爬取目標(biāo)網(wǎng)站鏈接:http://tuan.bookschina.com/。獲取圖書網(wǎng)頁面信息要用到相關(guān)的類庫,打開網(wǎng)站看到的頁面信息是動態(tài)加載的。嘗試考慮先抓取圖書信息的第一頁開始,我使用的是chrome瀏覽器,并設(shè)置開發(fā)模式,可以查看相關(guān)頁面的相應(yīng)加載信息,我們需要通過查看header信息,完成實(shí)現(xiàn)模擬登陸實(shí)現(xiàn)的功能。
對爬取圖書網(wǎng)目標(biāo)的定義和描述。在聚焦圖書網(wǎng)絡(luò)爬蟲中,首先我們要依據(jù)爬取圖書網(wǎng)需求定義,并聚焦圖書網(wǎng)絡(luò)爬蟲的爬取目標(biāo),以及進(jìn)行對應(yīng)相關(guān)的描述。獲取初始的URL。根據(jù)初始的URL爬取頁面,并獲得新的URL。從新的URL中過濾掉與爬取目標(biāo)無關(guān)的鏈接。因?yàn)榫劢咕W(wǎng)絡(luò)爬蟲對網(wǎng)頁的爬取是有目的性的,所以與目標(biāo)無關(guān)的網(wǎng)頁將會被過濾掉。同時,也需要將已爬取的URL地址存放到一個URL列表中,用于去重和判斷爬取的進(jìn)程。將過濾后的鏈接放到URL隊(duì)列中。從URL隊(duì)列中,根據(jù)搜索算法,確定URL的優(yōu)先級,并確定下一步要爬取的URL地址。網(wǎng)絡(luò)爬蟲的實(shí)現(xiàn)原理以及相應(yīng)的工作原理如圖1所示。
圖1 圖書網(wǎng)爬蟲運(yùn)行原理
在通用網(wǎng)絡(luò)爬蟲中,下一步爬取哪些URL地址,是不太重要的,但是在聚焦網(wǎng)絡(luò)爬蟲中,由于其具有目的性,故而下一步爬取哪些URL地址相對來說是比較重要的。對于聚焦網(wǎng)絡(luò)爬蟲來說,不同的爬取順序,可能導(dǎo)致爬蟲的執(zhí)行效率不同,所以,我們需要依據(jù)搜索策略來確定下一步需要爬取哪些URL地址。從下一步要爬取的URL地址中,讀取新的URL,然后依據(jù)新的URL地址爬取網(wǎng)頁,并重復(fù)上述爬取過程。滿足系統(tǒng)中設(shè)置的停止條件時,或無法獲取新的URL地址時,停止爬行。
通過分析分析整個圖書網(wǎng)的DOM,可以查看所需要的信息都封裝在哪些tags的里面,經(jīng)過遍歷搜索后,發(fā)現(xiàn)到所需要的信息其實(shí)都封裝在
可以通過調(diào)用requests里get方法,獲得到了響應(yīng)的response,然后通過BS進(jìn)行解析,在class 名為taoListInner的div標(biāo)簽中,封裝了我們需要的ul下的li,查看了beautifulsoup調(diào)用select方法拿到對應(yīng)的標(biāo)簽,然后拿到對應(yīng)h2標(biāo)簽下的書名[4]。salePrice class下的價格;以及img標(biāo)簽內(nèi)src的預(yù)覽圖鏈接。這樣就可以得到出我們需要的第一頁所顯示的書籍的信息了。要想獲取頁面的更多書籍信息,由于bs的select方法是只能解析靜態(tài)的Dom的,因此更多的圖書數(shù)據(jù)是通過Ajax或者JS加載的,查看開發(fā)者模式的XHR里面的內(nèi)容后發(fā)現(xiàn),當(dāng)下拉滾動條并得到最新圖書信息的時候,會繼續(xù)刷新出一個對應(yīng)的鏈接,打開并查看Preview里面,封裝了我們需要的數(shù)據(jù),并且是以Json形式進(jìn)行保存的,這樣便能使我們方便地拿到動態(tài)生成的圖書數(shù)據(jù)了。想要拿到我們需要的Json數(shù)據(jù),首先需要去獲得相應(yīng)的Request URL。
當(dāng)每次有新的書籍信息刷新一次的時候,生成的GroupList?...URL中的Page=?跟隨著也會不斷遞增,因此需要去通過遍歷URL并拿到返回的JSON進(jìn)行解析,這樣就可以得到我們想要的所有數(shù)據(jù)了,當(dāng)遇到許多動態(tài)加載的網(wǎng)站,都會把以Json數(shù)據(jù)封裝作為response,爬蟲通過調(diào)用loads()方法,把返回的json數(shù)據(jù)轉(zhuǎn)換為python的字典,方便拿數(shù)據(jù)拿到數(shù)據(jù)后我們決定把數(shù)據(jù)存入磁盤,生成cvs的excel文件,寫入到相關(guān)的文件中,為了讓獲得的信息做進(jìn)一步的數(shù)據(jù)分析。
要實(shí)現(xiàn)整個過程中并發(fā)訪問程序,需要編寫并發(fā)訪問程序?qū)崿F(xiàn)多線程同步。通過爬蟲程序會先去獲得網(wǎng)站的url,然后對url內(nèi)的json數(shù)據(jù)進(jìn)行處理,之后寫入文件,所以在整個過程中,我們可以分別讓多個進(jìn)程去獲得url中response的數(shù)據(jù),然后進(jìn)行分批地處理,寫入文件中,在python中,每個進(jìn)程都有一個互斥鎖,可以保證同一時間內(nèi)只能有一個線程運(yùn)行,通過找到遍歷url的方法,然后把方法體進(jìn)一步地封裝到scraping_page_data()方法里,并創(chuàng)建線程池。
進(jìn)行調(diào)用join方法后,子進(jìn)程會在主進(jìn)程結(jié)束后不再繼續(xù)執(zhí)行。主進(jìn)程會去等待其他的進(jìn)程,在進(jìn)程池中使用apply方法去實(shí)現(xiàn)每個子進(jìn)程,要執(zhí)行apply(method_name, (parameters....))的方法。由于我們想要確保每次獲得一條url,當(dāng)前進(jìn)程寫入的數(shù)據(jù)的時候,不被其他進(jìn)程打擾,使用給寫入操作加上進(jìn)程鎖后,在寫的過程中可以知道,如果按照創(chuàng)建一條進(jìn)程的方法也創(chuàng)建進(jìn)程鎖,會報(bào)錯,原因是用了進(jìn)程池,而進(jìn)程池中的進(jìn)程并不是由當(dāng)前同一個父進(jìn)程創(chuàng)建的原因[5]。multiprocessing.Manager()返回的manager對象控制了一個server進(jìn)程,可用于多進(jìn)程之間的安全通信。
Python擁有很強(qiáng)大的關(guān)于科學(xué)計(jì)算庫,如Numpy庫在數(shù)值計(jì)算領(lǐng)域中可以用來存儲和處理大型矩陣,矩陣運(yùn)算、矢量處理、精密運(yùn)算等數(shù)值編程。SymPy庫用于數(shù)學(xué)符號的計(jì)算庫,如數(shù)學(xué)中常用的自然數(shù)E、圓周率pi、虛數(shù)i等進(jìn)行數(shù)學(xué)公式的符號演算推導(dǎo)及證明。Matplotlib庫可以把基于科學(xué)的數(shù)據(jù)可視化展示,生成如曲線、直方圖、2D、3D等根據(jù)需要的各種圖形,它是Python面向?qū)ο笾睦L圖庫,提供了許多方便調(diào)用的API命令。
Python擴(kuò)充程序庫中Matplotlib庫可以完成2D繪圖庫,這使得通過編程可以形象直觀完成圖形圖表的繪制,使用Matplotlib類庫對于數(shù)據(jù)圖形化處理生成柱狀圖,通過執(zhí)行寫入操作獲得數(shù)據(jù)后,需要讀取cvs中的price,分析價格低于100元的圖書的價位分布,可以引入matplotlib包來生成統(tǒng)計(jì)圖如圖2所示。
圖2 圖書價位統(tǒng)計(jì)圖
伴隨著互聯(lián)網(wǎng)技術(shù)的不斷發(fā)展,大量的公共信息更容易獲得,使用爬蟲技術(shù)將作為獲取這些信息的載體工具。面對第四次工業(yè)革命的發(fā)展,人工智能與物聯(lián)網(wǎng)將引領(lǐng)IT技術(shù)走向新的應(yīng)用,Python網(wǎng)絡(luò)爬蟲作為科技浪潮領(lǐng)域數(shù)據(jù)應(yīng)用的技術(shù)。大數(shù)據(jù)時代對數(shù)據(jù)分析與數(shù)據(jù)挖掘有著廣泛需求,利用Pyhton爬蟲使用的第三方庫函數(shù)就能實(shí)現(xiàn)數(shù)值分析的應(yīng)用優(yōu)勢,因此越來越多的程序員和科研人員也開始使用Pyhton爬蟲技術(shù)完成輔助數(shù)據(jù)分析工作,日常生活中人們使用智能手機(jī)和各種智能設(shè)備每天都會產(chǎn)生海量的數(shù)據(jù),相信不遠(yuǎn)的未來,隨著物聯(lián)網(wǎng)的普及,大量的智能終端設(shè)備產(chǎn)生的數(shù)據(jù)一定會成幾何級數(shù)的增長,因?yàn)槊媾R數(shù)據(jù)采集的規(guī)模將是空前的。今后很好的處理這些數(shù)據(jù),可以為各種公司篩選需要發(fā)送定制服務(wù)的精準(zhǔn)客戶。高職院校軟件相關(guān)專業(yè)也涉及相關(guān)課程內(nèi)容,幫助學(xué)生探索培養(yǎng)人工智能時代的編程思維。
本文是基于python爬蟲技術(shù)實(shí)現(xiàn)圖書網(wǎng)相關(guān)數(shù)據(jù)爬取,圖書價格可視化的應(yīng)用。使用第三方庫實(shí)現(xiàn)圖書頁面信息獲取,并利用統(tǒng)計(jì)分析方法庫函數(shù),進(jìn)行了提取圖書信息價格的柱狀圖繪制,這個數(shù)據(jù)的可視化展示利用分析過程的展示,今后教學(xué)實(shí)踐將繼續(xù)以Python網(wǎng)絡(luò)爬蟲為載體,“新工科”建設(shè)為指導(dǎo),設(shè)計(jì)和挖掘更多基于Pyhton網(wǎng)絡(luò)爬蟲的應(yīng)用案例,提升教育教學(xué)水平和激發(fā)學(xué)生學(xué)習(xí)興趣。