孫澤龍
(西安職業(yè)技術(shù)學(xué)院,陜西西安,710077)
由于現(xiàn)在絕大多數(shù)圖書(shū)網(wǎng)站都是基于一定的模板開(kāi)發(fā)的,使用相關(guān)的模板,可以快速完成相同版式且不同內(nèi)容的大量頁(yè)面,通過(guò)這個(gè)規(guī)律只要把相同的內(nèi)容都獲取下來(lái),求同存異地獲取實(shí)現(xiàn)大量頁(yè)面的目的[1]。
Python實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)需要手動(dòng)安裝第三方庫(kù)。Python爬蟲(chóng)需要HTTP請(qǐng)求,它可以理解為是從客戶端到服務(wù)器端的請(qǐng)求消息。即就是說(shuō),無(wú)論是真正的一個(gè)人在操作瀏覽器還是一個(gè)爬蟲(chóng),當(dāng)希望從服務(wù)器請(qǐng)求信息或服務(wù)時(shí),首先就需要向服務(wù)器端發(fā)出一個(gè)請(qǐng)求,進(jìn)而服務(wù)器會(huì)返回相應(yīng)響應(yīng),最后連接關(guān)閉,Web服務(wù)的流程就是這樣完成的。本文用到的庫(kù)函數(shù)包含requests庫(kù),使用requests庫(kù)調(diào)用get()和set()兩種提交方法獲取圖書(shū)網(wǎng)站源碼,如果網(wǎng)址需要提交的內(nèi)容是JSON格式,要進(jìn)行調(diào)用修改post()方法的一些參數(shù)。編碼格式用很多種,通過(guò)相關(guān)圖書(shū)網(wǎng)站編碼的測(cè)試,大多數(shù)情況下使用”utf-8”可以進(jìn)行中文正常顯示。單網(wǎng)絡(luò)爬蟲(chóng)是只有一個(gè)線程和進(jìn)程,每次爬取訪問(wèn)一個(gè)頁(yè)面,為了提高爬取效率和充分使用計(jì)算機(jī)網(wǎng)絡(luò)帶寬,一次同時(shí)讓爬蟲(chóng)訪問(wèn)多個(gè)頁(yè)面的目的,將使用多進(jìn)程技術(shù),通過(guò)調(diào)用multiprocessing多進(jìn)程庫(kù),處理多進(jìn)程的相關(guān)操作。因?yàn)榕老x(chóng)屬于讀寫(xiě)操作密集型的事情,當(dāng)我們?cè)L問(wèn)請(qǐng)求網(wǎng)頁(yè)相關(guān)源碼時(shí),多線程省去了大量等待返回網(wǎng)頁(yè)的時(shí)間[2]。當(dāng)然,對(duì)于訪問(wèn)數(shù)量達(dá)到一定數(shù)量級(jí)時(shí),多線程需要通過(guò)異步操作來(lái)保持自身爬蟲(chóng)運(yùn)行的效率。
查看圖書(shū)網(wǎng)的網(wǎng)頁(yè)源碼后可以看出,它是一種結(jié)構(gòu)化的數(shù)據(jù),通過(guò)分析網(wǎng)頁(yè)結(jié)構(gòu)信息,Python的第三方庫(kù)BeautifulSoup4,可以用來(lái)提取HTML和XML頁(yè)面結(jié)構(gòu)內(nèi)容,一般需要處理解析源代碼從而生成BeautifulSoup對(duì)象,找到包含特殊屬性的標(biāo)簽,使用find()方法完成查找內(nèi)容。Python對(duì)文本文件操作中,可以導(dǎo)入CSV模塊完成對(duì)CSV文件的讀取,而且CSV文件用Excel應(yīng)用打開(kāi)時(shí)可讀性高[3]。
解析器重要的功能是完成過(guò)濾選取網(wǎng)絡(luò)信息的作用。選取解析器的優(yōu)劣直接決定了網(wǎng)絡(luò)爬蟲(chóng)的執(zhí)行速度和效率。Beautiful Soup不僅支持Python標(biāo)準(zhǔn)庫(kù)中的HTML解析器外,還支持一些第三方如lxml HTML、lxml XML、html5lib的解析器。Beautiful Soup的解析器對(duì)比如表1所示,列出了其目前主要的解析器,以及它們各自的優(yōu)缺點(diǎn)。

表1 BeautifulSoup解析器對(duì)比
本文以圖書(shū)網(wǎng)為案例來(lái)說(shuō)明,爬取目標(biāo)內(nèi)容為圖書(shū)的名稱、價(jià)格及對(duì)應(yīng)圖書(shū)預(yù)覽圖的鏈接,爬取目標(biāo)網(wǎng)站鏈接:http://tuan.bookschina.com/。獲取圖書(shū)網(wǎng)頁(yè)面信息要用到相關(guān)的類庫(kù),打開(kāi)網(wǎng)站看到的頁(yè)面信息是動(dòng)態(tài)加載的。嘗試考慮先抓取圖書(shū)信息的第一頁(yè)開(kāi)始,我使用的是chrome瀏覽器,并設(shè)置開(kāi)發(fā)模式,可以查看相關(guān)頁(yè)面的相應(yīng)加載信息,我們需要通過(guò)查看header信息,完成實(shí)現(xiàn)模擬登陸實(shí)現(xiàn)的功能。
對(duì)爬取圖書(shū)網(wǎng)目標(biāo)的定義和描述。在聚焦圖書(shū)網(wǎng)絡(luò)爬蟲(chóng)中,首先我們要依據(jù)爬取圖書(shū)網(wǎng)需求定義,并聚焦圖書(shū)網(wǎng)絡(luò)爬蟲(chóng)的爬取目標(biāo),以及進(jìn)行對(duì)應(yīng)相關(guān)的描述。獲取初始的URL。根據(jù)初始的URL爬取頁(yè)面,并獲得新的URL。從新的URL中過(guò)濾掉與爬取目標(biāo)無(wú)關(guān)的鏈接。因?yàn)榫劢咕W(wǎng)絡(luò)爬蟲(chóng)對(duì)網(wǎng)頁(yè)的爬取是有目的性的,所以與目標(biāo)無(wú)關(guān)的網(wǎng)頁(yè)將會(huì)被過(guò)濾掉。同時(shí),也需要將已爬取的URL地址存放到一個(gè)URL列表中,用于去重和判斷爬取的進(jìn)程。將過(guò)濾后的鏈接放到URL隊(duì)列中。從URL隊(duì)列中,根據(jù)搜索算法,確定URL的優(yōu)先級(jí),并確定下一步要爬取的URL地址。網(wǎng)絡(luò)爬蟲(chóng)的實(shí)現(xiàn)原理以及相應(yīng)的工作原理如圖1所示。

圖1 圖書(shū)網(wǎng)爬蟲(chóng)運(yùn)行原理
在通用網(wǎng)絡(luò)爬蟲(chóng)中,下一步爬取哪些URL地址,是不太重要的,但是在聚焦網(wǎng)絡(luò)爬蟲(chóng)中,由于其具有目的性,故而下一步爬取哪些URL地址相對(duì)來(lái)說(shuō)是比較重要的。對(duì)于聚焦網(wǎng)絡(luò)爬蟲(chóng)來(lái)說(shuō),不同的爬取順序,可能導(dǎo)致爬蟲(chóng)的執(zhí)行效率不同,所以,我們需要依據(jù)搜索策略來(lái)確定下一步需要爬取哪些URL地址。從下一步要爬取的URL地址中,讀取新的URL,然后依據(jù)新的URL地址爬取網(wǎng)頁(yè),并重復(fù)上述爬取過(guò)程。滿足系統(tǒng)中設(shè)置的停止條件時(shí),或無(wú)法獲取新的URL地址時(shí),停止爬行。
通過(guò)分析分析整個(gè)圖書(shū)網(wǎng)的DOM,可以查看所需要的信息都封裝在哪些tags的里面,經(jīng)過(guò)遍歷搜索后,發(fā)現(xiàn)到所需要的信息其實(shí)都封裝在
可以通過(guò)調(diào)用requests里get方法,獲得到了響應(yīng)的response,然后通過(guò)BS進(jìn)行解析,在class 名為taoListInner的div標(biāo)簽中,封裝了我們需要的ul下的li,查看了beautifulsoup調(diào)用select方法拿到對(duì)應(yīng)的標(biāo)簽,然后拿到對(duì)應(yīng)h2標(biāo)簽下的書(shū)名[4]。salePrice class下的價(jià)格;以及img標(biāo)簽內(nèi)src的預(yù)覽圖鏈接。這樣就可以得到出我們需要的第一頁(yè)所顯示的書(shū)籍的信息了。要想獲取頁(yè)面的更多書(shū)籍信息,由于bs的select方法是只能解析靜態(tài)的Dom的,因此更多的圖書(shū)數(shù)據(jù)是通過(guò)Ajax或者JS加載的,查看開(kāi)發(fā)者模式的XHR里面的內(nèi)容后發(fā)現(xiàn),當(dāng)下拉滾動(dòng)條并得到最新圖書(shū)信息的時(shí)候,會(huì)繼續(xù)刷新出一個(gè)對(duì)應(yīng)的鏈接,打開(kāi)并查看Preview里面,封裝了我們需要的數(shù)據(jù),并且是以Json形式進(jìn)行保存的,這樣便能使我們方便地拿到動(dòng)態(tài)生成的圖書(shū)數(shù)據(jù)了。想要拿到我們需要的Json數(shù)據(jù),首先需要去獲得相應(yīng)的Request URL。
當(dāng)每次有新的書(shū)籍信息刷新一次的時(shí)候,生成的GroupList?...URL中的Page=?跟隨著也會(huì)不斷遞增,因此需要去通過(guò)遍歷URL并拿到返回的JSON進(jìn)行解析,這樣就可以得到我們想要的所有數(shù)據(jù)了,當(dāng)遇到許多動(dòng)態(tài)加載的網(wǎng)站,都會(huì)把以Json數(shù)據(jù)封裝作為response,爬蟲(chóng)通過(guò)調(diào)用loads()方法,把返回的json數(shù)據(jù)轉(zhuǎn)換為python的字典,方便拿數(shù)據(jù)拿到數(shù)據(jù)后我們決定把數(shù)據(jù)存入磁盤,生成cvs的excel文件,寫(xiě)入到相關(guān)的文件中,為了讓獲得的信息做進(jìn)一步的數(shù)據(jù)分析。
要實(shí)現(xiàn)整個(gè)過(guò)程中并發(fā)訪問(wèn)程序,需要編寫(xiě)并發(fā)訪問(wèn)程序?qū)崿F(xiàn)多線程同步。通過(guò)爬蟲(chóng)程序會(huì)先去獲得網(wǎng)站的url,然后對(duì)url內(nèi)的json數(shù)據(jù)進(jìn)行處理,之后寫(xiě)入文件,所以在整個(gè)過(guò)程中,我們可以分別讓多個(gè)進(jìn)程去獲得url中response的數(shù)據(jù),然后進(jìn)行分批地處理,寫(xiě)入文件中,在python中,每個(gè)進(jìn)程都有一個(gè)互斥鎖,可以保證同一時(shí)間內(nèi)只能有一個(gè)線程運(yùn)行,通過(guò)找到遍歷url的方法,然后把方法體進(jìn)一步地封裝到scraping_page_data()方法里,并創(chuàng)建線程池。
進(jìn)行調(diào)用join方法后,子進(jìn)程會(huì)在主進(jìn)程結(jié)束后不再繼續(xù)執(zhí)行。主進(jìn)程會(huì)去等待其他的進(jìn)程,在進(jìn)程池中使用apply方法去實(shí)現(xiàn)每個(gè)子進(jìn)程,要執(zhí)行apply(method_name, (parameters....))的方法。由于我們想要確保每次獲得一條url,當(dāng)前進(jìn)程寫(xiě)入的數(shù)據(jù)的時(shí)候,不被其他進(jìn)程打擾,使用給寫(xiě)入操作加上進(jìn)程鎖后,在寫(xiě)的過(guò)程中可以知道,如果按照創(chuàng)建一條進(jìn)程的方法也創(chuàng)建進(jìn)程鎖,會(huì)報(bào)錯(cuò),原因是用了進(jìn)程池,而進(jìn)程池中的進(jìn)程并不是由當(dāng)前同一個(gè)父進(jìn)程創(chuàng)建的原因[5]。multiprocessing.Manager()返回的manager對(duì)象控制了一個(gè)server進(jìn)程,可用于多進(jìn)程之間的安全通信。
Python擁有很強(qiáng)大的關(guān)于科學(xué)計(jì)算庫(kù),如Numpy庫(kù)在數(shù)值計(jì)算領(lǐng)域中可以用來(lái)存儲(chǔ)和處理大型矩陣,矩陣運(yùn)算、矢量處理、精密運(yùn)算等數(shù)值編程。SymPy庫(kù)用于數(shù)學(xué)符號(hào)的計(jì)算庫(kù),如數(shù)學(xué)中常用的自然數(shù)E、圓周率pi、虛數(shù)i等進(jìn)行數(shù)學(xué)公式的符號(hào)演算推導(dǎo)及證明。Matplotlib庫(kù)可以把基于科學(xué)的數(shù)據(jù)可視化展示,生成如曲線、直方圖、2D、3D等根據(jù)需要的各種圖形,它是Python面向?qū)ο笾睦L圖庫(kù),提供了許多方便調(diào)用的API命令。
Python擴(kuò)充程序庫(kù)中Matplotlib庫(kù)可以完成2D繪圖庫(kù),這使得通過(guò)編程可以形象直觀完成圖形圖表的繪制,使用Matplotlib類庫(kù)對(duì)于數(shù)據(jù)圖形化處理生成柱狀圖,通過(guò)執(zhí)行寫(xiě)入操作獲得數(shù)據(jù)后,需要讀取cvs中的price,分析價(jià)格低于100元的圖書(shū)的價(jià)位分布,可以引入matplotlib包來(lái)生成統(tǒng)計(jì)圖如圖2所示。

圖2 圖書(shū)價(jià)位統(tǒng)計(jì)圖
伴隨著互聯(lián)網(wǎng)技術(shù)的不斷發(fā)展,大量的公共信息更容易獲得,使用爬蟲(chóng)技術(shù)將作為獲取這些信息的載體工具。面對(duì)第四次工業(yè)革命的發(fā)展,人工智能與物聯(lián)網(wǎng)將引領(lǐng)IT技術(shù)走向新的應(yīng)用,Python網(wǎng)絡(luò)爬蟲(chóng)作為科技浪潮領(lǐng)域數(shù)據(jù)應(yīng)用的技術(shù)。大數(shù)據(jù)時(shí)代對(duì)數(shù)據(jù)分析與數(shù)據(jù)挖掘有著廣泛需求,利用Pyhton爬蟲(chóng)使用的第三方庫(kù)函數(shù)就能實(shí)現(xiàn)數(shù)值分析的應(yīng)用優(yōu)勢(shì),因此越來(lái)越多的程序員和科研人員也開(kāi)始使用Pyhton爬蟲(chóng)技術(shù)完成輔助數(shù)據(jù)分析工作,日常生活中人們使用智能手機(jī)和各種智能設(shè)備每天都會(huì)產(chǎn)生海量的數(shù)據(jù),相信不遠(yuǎn)的未來(lái),隨著物聯(lián)網(wǎng)的普及,大量的智能終端設(shè)備產(chǎn)生的數(shù)據(jù)一定會(huì)成幾何級(jí)數(shù)的增長(zhǎng),因?yàn)槊媾R數(shù)據(jù)采集的規(guī)模將是空前的。今后很好的處理這些數(shù)據(jù),可以為各種公司篩選需要發(fā)送定制服務(wù)的精準(zhǔn)客戶。高職院校軟件相關(guān)專業(yè)也涉及相關(guān)課程內(nèi)容,幫助學(xué)生探索培養(yǎng)人工智能時(shí)代的編程思維。
本文是基于python爬蟲(chóng)技術(shù)實(shí)現(xiàn)圖書(shū)網(wǎng)相關(guān)數(shù)據(jù)爬取,圖書(shū)價(jià)格可視化的應(yīng)用。使用第三方庫(kù)實(shí)現(xiàn)圖書(shū)頁(yè)面信息獲取,并利用統(tǒng)計(jì)分析方法庫(kù)函數(shù),進(jìn)行了提取圖書(shū)信息價(jià)格的柱狀圖繪制,這個(gè)數(shù)據(jù)的可視化展示利用分析過(guò)程的展示,今后教學(xué)實(shí)踐將繼續(xù)以Python網(wǎng)絡(luò)爬蟲(chóng)為載體,“新工科”建設(shè)為指導(dǎo),設(shè)計(jì)和挖掘更多基于Pyhton網(wǎng)絡(luò)爬蟲(chóng)的應(yīng)用案例,提升教育教學(xué)水平和激發(fā)學(xué)生學(xué)習(xí)興趣。