張喜紅
(亳州職業技術學院智能工程系,安徽亳州 236800)
伴隨著大數據時代的快速到來,人們越來越傾向于借助數據揭示事物內在規律,進而指導決策[1-2].因此,如何利用大數據做好中藥材價格走勢的及時預測,為中藥材市場運營決策提供支撐,促進市場有序運營,極具研究意義.目前對于價格推測、分析的方法主要有兩類,其一是基于影響價格變化因素采用特定的技術方法進行推理;其二是基于歷史數據的推理法.因素法由于影響因子多維善變、因子權重難于確定等原因,難于建模;時間序列分析是一種基于歷史價格數據的變化規律預測未來價格走勢的方法,是當前價格預測的主流方法之一.時間序列分析法實施的難點在于如何獲取足夠多且相對完整的歷史價格數據[3].
互聯網技術自誕生以來,在各行業得到了廣泛的應用,互聯網在中醫、中藥領域的應用也達到了前所未有的廣度,積累了相當豐厚的網絡數據資源.如中藥材天地網就積累了相當數量的中藥材價格信息,為時間序列分析法提供了強有力的數據支撐.然而,如何從網絡上快速、高效的收集這些數據,并將其整理為便于分析的結構化數據,是極為關鍵的一步.網絡爬蟲是收集、提取網絡數據的主流技術手段[4-5].
基于上述背景,為了滿足基于時間序列分析法開展中藥材價格預測研究的數據需求,鑒于Python語言在爬蟲設計方面具有程序簡潔、資源豐富、便于實現等優點,本文以中藥材天地網為目標網站,基于Python語言設計了一款用于中藥材價格信息收集的網絡爬蟲,采用Requests模塊實現網頁的Http請求,采用Beautifulsoup實現了目標信息的過濾、解析、提取,最終將目標數據保存為便于分析的結構化文本文件數據,同時就爬蟲的定時啟動、抓取進行了介紹.
從互聯網獲取相關信息,最直接的方法是通過瀏覽器輸入URL向服務器發起Http請求,請求成功后服務器返回一個包含目標網頁內容的Response,經瀏覽器解析后呈現給用戶.如果用戶想統計、收集某個網站成千上萬條的信息記錄條,若以瀏覽器人工訪問網頁的方式進行,不僅效率低下且易出錯[6].基于此,爬蟲的概念便誕生了,爬蟲通俗來講是一段實現自動訪問網頁,并自動定向提取網頁中目標信息的程序.網絡爬蟲典型的工作流程大致包含如下幾個步驟:①模擬或自動調用網頁瀏覽器發送請求并獲取網頁源碼;如在Python中可使用Request庫的相關方法向服務器發起模擬請求,待響應成功后,將返回一個包含多種媒體格式的Response.②過濾、提取網頁源碼中包含的目標信息;即從網頁源碼中通過XPath、正則表達式或Beautifulsoup等模塊的相應方法,定位、提取目標信息.③將提取的目標信息存儲;保存形式多樣化,可以保存成文本,也可以保存至數據庫,或者保存成特定格式的文件.
中藥材天地網自建站以來,其市場價格欄目每天實時公布亳州、安國、玉林及荷花池4個藥市數百種中藥材的規格與價格信息,且其公布的中藥材價格數據真實可靠,為中藥材價格走勢的預測提供了真實、可靠的源數據.在網頁瀏覽器中輸入藥材價格欄目的首頁URL地址:http://www.zyctd.com/jiage/1-0-0.html,可得到圖1所示的頁面,在頁面的價格信息區按品名、規格、市場、當前價格等題頭逐行呈現中藥材的價格信息,且分多頁顯示,在頁面的底部給出了分頁鏈接信息.根據上述分析可知,在爬蟲的設計過程中,需要解決如下問題:①獲取各個分頁的URL鏈接地址;②提取各分頁信息記錄條的目標信息.
如前面所述爬蟲要想從網頁中提取信息,首先需將網頁源碼下載到本地,網頁源碼的下載通過Http請求實現,Requests模塊是Python語言開發的Http庫,其功能強大,實現簡單[7-9].對于采用GET方式打開的網頁,可采用語句requests.get(“URL地址參數”).text方法模擬請求,得到網頁源后將其存儲為文本格式.同時BeautifulSoup是基于Python語言開發的一個用于解析html對象的第三方庫.對于結構化網頁信息的提取,與正則表達式相比更具優勢.其提供的find()與find_all()方法使信息定位、過濾、提取的實現更加簡單[10-13].同時考慮到中藥材天地網結構規范,且要提取的目標信息都是文本字段,最終決定采用Requests模塊進行模擬Http請求下載目標網頁源碼,采用BeautifulSoup模塊過濾、解析、提取目標信息.
借助瀏覽器的審查元素工具,分析各頁中的源碼架構,如圖2所示,每頁中的每條信息記錄條處于同一
def get_page_values(self, now_url): # 其中now_url參數為網頁的URL地址
now_html = requests.get(now_url).text # 下載網頁源碼,并以文本方式儲存
now_Soup = BeautifulSoup(now_html, 'lxml')# 以網頁文檔解析源碼
all_value_li = now_Soup.find('div', class_='priceTable').find_all('li')#定位所有
for tag in all_value_li:#遍歷所有
name = tag.find('span', class_='w1').get_text().encode('utf-8')
#提取“品名”
guige = tag.find('span', class_='w2').get_text().encode('utf-8')
#提取“規格”
shichang = tag.find('span', class_='w9').get_text().encode('utf-8')
#提取“市場”
price = tag.find('span', class_='w3').get_text().encode('utf-8')
#提取“價格”
self.write_txt(name, guige, shichang, price)#將目標信息存入文件
通過瀏覽器查看各個分頁的URL地址可知:各分頁的URL地址是由首頁URL地址加一個“-”與分頁號構成,如:首頁的URL地址為:http://www.zyctd.com/jiage/1-0-0.html,第201頁的URL地址為:http://www.zyctd.com/jiage/1-0-0-201.html.如圖1(b)所示,首頁底部的分頁鏈接按鈕給出了分頁面的總數,如當前一共有201個頁面.通過審查元素工具,可知分頁總數位于
def get_all_page_values(self):#獲取所有分頁面中記錄條信息
# 下載首頁源碼
html = requests.get('http://www.zyctd.com/jiage/1-0-0.html').text
# 以網頁解析文檔
Soup = BeautifulSoup(html, 'lxml')
# 定位到最后一頁的頁碼值對應的標簽區
all_li = Soup.find('div', class_='pageBreak').find_all('a')
# 提取最后一頁的頁碼值,#獲取最大頁碼值,即頁面總數
Page_max = int(all_li[4].get_text())
all_page_value = []
for i in range(1, Page_max + 1):
if i == 1:
# 為1時是首頁,URL地址較特殊
temp_url = 'http://www.zyctd.com/jiage/1-0-0.html' else:
# 字串拼接構造分頁URL地址
temp_url = 'http://www.zyctd.com/jiage/1-0-0-' + str(i) + '.html'
# 調用頁面目標信息提取函數,獲取當前分頁中所有記錄條的品名、規格、市場、價格等目標信息
now_page = self.get_values(temp_url)
all_page_value.extend(now_page)
result_df = pd.DataFrame(all_page_value)
returnresult_df
鑒于文本文件的通用性較好,且便于后期的跨平臺分析,文中將提取到的目標數據采用文本文件進行存儲.為了便于后期按分隔符導入表格文件,在寫入文本文件時,一條記錄條的品名、規格、市場及價格之間采用逗號分隔,各條記錄條間采用回車進行分隔.同時考慮到中藥材天地網的價格信息是按天發布,為了避免信息的重復,在每天爬取數據時,以當前系統日期為文件名創建文件,當前系統日期的獲取通過Python的datetime模塊中的datetime.now().date().isoformat()實現.詳細實現代碼如下:
def write_txt(self,name,guige,shichang,price):
#以當前系統日期為文件名創建本次存儲文件
file_name=str(self.path_)+'/'+datetime.now().date().isoformat()+'.txt'
with open(file_name, 'a') as f:
f.write(name)#品名
f.write(',')#逗號分隔
f.write(guige)#規格
f.write(',')#逗號分隔
f.write(shichang)#市場
f.write(',')#逗號分隔
f.write(price)#價格
f.write(' ')#不同記錄條間“回車”分隔
中藥材天地網按天更新各藥材價格信息,因此需每天運行爬蟲,對更新的價格進行采集,如果爬蟲每天的啟動工作由用戶人工完成,事必增加了用戶的工作事項,多有不便.倘若有一天用戶忘記了此項任務,將會導致當天信息缺失.考慮到當前用戶電腦以windows系統為主流,同時windows系統自帶任務計劃程序安排功能,因此采用windows自帶的任務計劃來實現爬蟲的定時啟動.以Win7系統為例,具體的部署方法是:①創建bat批處理文件,在文件中書寫如:“python 爬蟲文件名.py”格式的命令;②依次進入系統“控制面板”/“管理工具”/“任務計劃程序”/“創建任務”欄目,創建一個每天指定時間啟動①中批處理文件的新任務;③在“任務計劃程序”任務安排列表中選中②中創建的新任務,并點選“運行”按鈕啟動.
將所設計的爬蟲按照上述方法,部署到CPU型號為Intel(R) Core(TM) i3-4160 3.6GHz,內存為4GB,操作系統為Win7-64位的平臺上,對目標網頁進行信息爬取,得到如圖3所示的目標信息,此次測試運行共計收集201頁20051條記錄,用時約1026毫秒.經人工與網頁實際數據對比,信息記錄條數一致,無重復,無缺項.進一步證實,所設計的爬蟲運行效率較高,準確無誤,可用于中藥材價格數據的收集.

圖3 目標信息片斷
本文以中藥材價格預測的研究為背景,為了收集大量的中藥材價格數據,瞄準互聯網上的數據資源,以中藥材天地網為目標網站,在深入分析其網頁布局結構及信息發布規則的基礎上,基于Python語言的Requests、Beautifulsoup等模塊,設計了一款中藥材價格信息爬蟲,同時就爬蟲在windows系統如何實現定時自動運行的部署進行了介紹.經實驗測試,所設計的爬蟲運行可靠、效率較高,所得數據與網頁公布一致無誤,為從互聯網收集中藥材相關信息提供了參考方法.雖然所設計的爬蟲能夠準確無誤的獲取中藥材價格信息,但是為了拓寬其使用人群范圍,需在后續的研究中解決其跨平臺部署不便的問題,讓其能脫離Python環境運行.