胡慶偉
(中海油國(guó)際貿(mào)易有限責(zé)任公司 北京市 100000)
隨著移動(dòng)互聯(lián)網(wǎng)、物聯(lián)網(wǎng)等新一代信息技術(shù)產(chǎn)業(yè)的快速發(fā)展,使得網(wǎng)絡(luò)數(shù)據(jù)量產(chǎn)生了爆炸式的增長(zhǎng),每個(gè)人每天都要面對(duì)海量信息的轟炸,身處這樣一個(gè)信息爆炸的時(shí)代,如何快速、有效的獲取信息變得尤為重要,如果能夠通過簡(jiǎn)單的編程,實(shí)現(xiàn)數(shù)據(jù)的自動(dòng)獲取、整理、分析,將極大的提升工作效率。大數(shù)據(jù)技術(shù)的發(fā)展促使網(wǎng)絡(luò)爬蟲技術(shù)應(yīng)用愈加廣泛,Python 編程語言因其簡(jiǎn)單易學(xué)的特性,使得更多非計(jì)算機(jī)專業(yè)人士也能夠通過編程,開發(fā)出簡(jiǎn)單的工具來輔助日常辦公。
在實(shí)際的辦公場(chǎng)景中,經(jīng)常需要每天到某網(wǎng)站收集數(shù)據(jù)的業(yè)務(wù),例如財(cái)務(wù)工作者需要每天到人民銀行官網(wǎng)查詢當(dāng)天人民幣對(duì)外幣的匯率,金融分析員需要在每天收盤后采集基金、股票、期貨的交易數(shù)據(jù),市場(chǎng)研究員需要每天訪問不同的網(wǎng)站收集市場(chǎng)信息等。如果有一個(gè)工具能夠每天定時(shí)的從網(wǎng)站采集數(shù)據(jù)并自動(dòng)地發(fā)送到郵箱中,相關(guān)工作人員就只需要按時(shí)去查看,就可以節(jié)省大量工作時(shí)間,同時(shí)還可為后續(xù)利用進(jìn)行數(shù)據(jù)分析和可視化奠定基礎(chǔ)。
Python 是由荷蘭數(shù)學(xué)和計(jì)算機(jī)科學(xué)研究學(xué)會(huì)的Guido van Rossum 于1989年底發(fā)明的一種解釋型、面向?qū)ο?、?dòng)態(tài)數(shù)據(jù)類型的高級(jí)程序設(shè)計(jì)語言,是一種效率極高的語言,使用Python 編寫時(shí),程序包含的代碼行數(shù)更少,代碼更容易閱讀、調(diào)試和擴(kuò)展,被廣泛用于編寫網(wǎng)絡(luò)爬蟲、游戲、創(chuàng)建Web 應(yīng)用程序等,不僅如此在科學(xué)領(lǐng)域也被大量運(yùn)用,其提供的科學(xué)計(jì)算擴(kuò)展庫(kù):NumPy、SciPy 和matplotlib,分別為Python 提供了快速數(shù)組處理、數(shù)值運(yùn)算以及繪圖功能,十分適合工程技術(shù)、科研人員處理實(shí)驗(yàn)數(shù)據(jù)、制作圖表,甚至開發(fā)科學(xué)計(jì)算應(yīng)用程序。本文中也將使用requests、openpyxl、pyinstaller 等第三方擴(kuò)展庫(kù),在使用之前需要通過pip install xxxx 命令進(jìn)行安裝。
數(shù)據(jù)采集模塊主要使用Python 第三方庫(kù)requests 提供的網(wǎng)絡(luò)爬蟲框架搭建,網(wǎng)絡(luò)爬蟲是一種根據(jù)預(yù)先設(shè)計(jì)好的規(guī)則,從特定網(wǎng)站中獲取相應(yīng)數(shù)據(jù)的工具,主要應(yīng)用于各種數(shù)據(jù)信息收集的場(chǎng)景,我們常見的百度、谷歌等搜索引擎就使用了網(wǎng)絡(luò)爬蟲技術(shù)。網(wǎng)絡(luò)爬蟲的實(shí)現(xiàn)通常分為四個(gè)關(guān)鍵步驟:
(1)數(shù)據(jù)獲取。首先需要分析目標(biāo)網(wǎng)站頁(yè)面,明確爬取的數(shù)據(jù)源。打開上海國(guó)際能源期貨交易中心每日交易快訊頁(yè)面URL 地 址:http://www.ine.cn/statements/daily/?name=kx, 經(jīng)觀察可知交易詳細(xì)數(shù)據(jù)會(huì)根據(jù)日期組件控制動(dòng)態(tài)刷新,由此判斷數(shù)據(jù)未直接存放在靜態(tài)HTML 頁(yè)面中,也就表示沒辦法使用BeautifulSoup 庫(kù)對(duì)提取的數(shù)據(jù)進(jìn)行解析。然后進(jìn)入開發(fā)者模式,檢查該Network 頁(yè)簽中動(dòng)態(tài)頁(yè)面加載情況,動(dòng)態(tài)數(shù)據(jù)一般存放在XHR 文件中,因此可以優(yōu)先查找XHR 中是否存放數(shù)據(jù)。經(jīng)過分析可以看到期貨交易數(shù)據(jù)實(shí)際保存的URL 地址為http://www.ine.cn/data/dailydata/kx/kx20210809.dat?temp2=1628514764422?r nd=0.028823041981317576,而該URL 中的“20210809”則控制具體顯示某天的數(shù)據(jù)。明確數(shù)據(jù)存放的URL 地址后,就可以開始編寫程序,在VS code 開發(fā)工具中新建名為download_ine.py 源文件,引用requests 庫(kù)、time 庫(kù),獲取當(dāng)天日期并拼接目標(biāo)URL 地址,為了避免網(wǎng)站的反爬蟲設(shè)置,需要加上User-Agent 偽裝成瀏覽器訪問,最后再使用requests.get()方法完成數(shù)據(jù)抓取,主要代碼如下:
import requests,time
today=time.strftime("%Y%m%d",time.localtime())#獲取交易日期
url='http://www.ine.cn/data/dailydata/kx/kx'+today+'.dat?temp2=16 28170114791?rnd=0.2163361727157722'#將URL 中特定的日期替換成參數(shù),確保程序每天都能找到對(duì)應(yīng)的頁(yè)面
headers={
'user-agent':'Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko) Chrome/90.0.4430.212 Safari/537.36'}
res=requests.get(url,headers=headers))#獲取頁(yè)面中的數(shù)據(jù)
(2)數(shù)據(jù)解析。通過前述分析可知交易詳細(xì)數(shù)據(jù)是動(dòng)態(tài)刷新的,因此步驟(1)獲取到的數(shù)據(jù)無法通過靜態(tài)頁(yè)面解析庫(kù)BeautifulSoap 進(jìn)行解析。這種能夠動(dòng)態(tài)刷新的數(shù)據(jù)被存放在名為JSON 的數(shù)據(jù)結(jié)構(gòu)中,可以使用requests 庫(kù)中的JSON 解碼器進(jìn)行解析,僅用一行代碼json_res=res.json()即可完成。
(3)數(shù)據(jù)提取。前面提到的JSON 是一種輕量級(jí)的文本數(shù)據(jù)交換格式,其具有的層次結(jié)構(gòu)與Python 中的字典、列表結(jié)構(gòu)較為類似,因此通過for 循環(huán)就可以將需要的數(shù)據(jù)字段如商品種類、交割月份、前結(jié)算、持倉(cāng)手、持倉(cāng)變化等逐行提取出來,并使用append 方法添加到自定義的data_list 列表中,主要代碼如下:
instrument_list =json_res['o_curinstrument']#將json 格式的數(shù)據(jù)轉(zhuǎn)換為列表
data_list =[]
for instrument in instrument_list:#循環(huán)列表提取數(shù)據(jù)
PRODUCTNAME=instrument['PRODUCTNAME']#商品種類DELIVERYMONTH=instrument['DELIVERYMONTH']#交割月份
......
OPENINTEREST=instrument['OPENINTEREST']#持倉(cāng)手
OPENINTERESTCHG=instrument['OPENINTERESTCHG']# 持倉(cāng)變化
data_list.append([PRODUCTNAME,DELIVERYMONTH,......,OP ENINTEREST,OPENINTERE
STCHG])
(4)數(shù)據(jù)存儲(chǔ)。常見的數(shù)據(jù)存儲(chǔ)方式有兩種,存儲(chǔ)為CSV 格式或Excel 文件,本文介紹第三方庫(kù)openpyxl 的使用方法,將數(shù)據(jù)存儲(chǔ)到Excel 文件,其基本操作流程為創(chuàng)建工作簿對(duì)象、激活sheet頁(yè)、循環(huán)填充數(shù)據(jù)、保存文件到指定路徑,主要代碼如下:
book = Workbook() #創(chuàng)建Workbook 對(duì)象
sheet = book.active #激活sheet 頁(yè)
for row in data_list: #循環(huán)列表并添加到Excel
sheet.append(row)
book.save("D:/Python/workspace/export_INE.xlsx")# 保存Excel文件
郵件發(fā)送功能需要用到Python 的smtplib、email 兩個(gè)庫(kù),其中smtplib 庫(kù)主要負(fù)責(zé)連接服務(wù)器、登錄、發(fā)送和退出,email 庫(kù)則主要處理郵件主題、收件人、發(fā)件人、正文、附件等。實(shí)現(xiàn)步驟大體包括連接郵件服務(wù)器、通過賬號(hào)密碼登錄郵箱、填寫收件人、填寫主題、撰寫正文、添加附件、發(fā)送郵件、退出郵箱八個(gè)部分,主要代碼如下:
sender = "xxx@qq.com"#發(fā)件人郵箱
password = "***"#發(fā)件人郵箱的密碼
to = "xxx@163.com"#收件人郵箱
msg = MIMEMultipart()#創(chuàng)建MIME
msg["Subject"]= "INE DATA --"+ today#添加郵件主題
msg["From"]= sender #添加發(fā)件人
msg["To"]= to #添加收件人
text = "上海國(guó)際能源交易中心期貨合約行情--""+today#添加正文內(nèi)容
multipart = MIMEText(text) #創(chuàng)建MIMEText
msg.attach(multipart)#添加到msg
multipart= MIMEApplication(open('D:/Python/workspace/export_INE.xlsx','rb').read())#讀取附件創(chuàng)建MIMEApplication
multipart.add_header('Content-Disposition','attachment',filename="
export_INE.xlsx")#添加信息頭
msg.attach(multipart)
s = smtplib.SMTP("smtp.qq.com", timeout=30) #連接郵件服務(wù)器
s.login(sender, password))#登錄郵箱
s.sendmail(sender, to,msg.as_string()) )#發(fā)送郵件
s.close()#關(guān)閉郵件連接
為了使Python 程序具有更強(qiáng)的適用性,可以將Python 源文件生成為.exe 可執(zhí)行文件,.exe 文件是一種不依賴于Python 開發(fā)運(yùn)行環(huán)境,可以在Windows 操作系統(tǒng)中直接運(yùn)行的文件類型,對(duì)非程序員的使用者更加友好。使用pyinstaller 第三方庫(kù)可以實(shí)現(xiàn)生成可執(zhí)行文件的操作,在安裝pyinstaller 時(shí)需要與Python 放到相同目錄,安裝完成后進(jìn)入download_ine.py 文件所在目錄,并運(yùn)行命令pyinstaller -F download_ine.py,參數(shù)“-F”表示將Python 程序生成為單個(gè)可執(zhí)行文件,從而避免因某些動(dòng)態(tài)庫(kù)文件丟失導(dǎo)致程序無法正確運(yùn)行。命令運(yùn)行完畢后會(huì)在當(dāng)前目錄新增加build 和dist 兩個(gè)目錄,新生成好download_ine.exe 可執(zhí)行文件存放在dist 文件夾中。
在Python 程序中,定時(shí)任務(wù)功能可以通過schedule 庫(kù)來實(shí)現(xiàn),但是這種方法需要將程序部署在服務(wù)器或持續(xù)運(yùn)行的PC 機(jī)上,并且安裝Python 運(yùn)行環(huán)境,對(duì)于普通使用者來說既不經(jīng)濟(jì),也不方便。因此,本文采取通過Windows 操作系統(tǒng)的“任務(wù)計(jì)劃程序”功能,實(shí)現(xiàn)數(shù)據(jù)采集工具程序的定時(shí)自動(dòng)運(yùn)行。在裝有Windows操作系統(tǒng)的電腦中,按順序打開“控制面板-管理工具-任務(wù)計(jì)劃程序”,新建基本任務(wù),選擇每日22:00 點(diǎn)運(yùn)行download_ine.exe程序,并勾選“錯(cuò)過計(jì)劃開始時(shí)間立即啟動(dòng)任務(wù)”選項(xiàng)。如此即可每日22:00 由操作系統(tǒng)自動(dòng)運(yùn)行download_ine.exe 程序,從上海國(guó)際能源交易中心網(wǎng)站上采集當(dāng)日期貨交易數(shù)據(jù)存儲(chǔ)到Excel 文件中,并通過郵件發(fā)送到指定的郵箱。
本文基于Python 程序語言,詳細(xì)介紹了從指定網(wǎng)站中進(jìn)行數(shù)據(jù)采集、數(shù)據(jù)解析、數(shù)據(jù)提取、數(shù)據(jù)存儲(chǔ)的過程,對(duì)發(fā)送郵件、生成可執(zhí)行文件、設(shè)置定時(shí)任務(wù)等進(jìn)行詳細(xì)闡述。通過實(shí)例詳細(xì)介紹了requests、openpyxl、smtplib、email、pyinstaller 等Python 自 有和第三方庫(kù)的使用方法。對(duì)于具有數(shù)據(jù)采集、郵件發(fā)送、定時(shí)任務(wù)等需求場(chǎng)景的讀者,本文提供了一種具有較高適用性的解決方案。