转载来源:用Python从四大期货交易所爬取数据[by lianzhang]
1.简介 为了获得免费且可靠的期货日行情数据,我设计并编写了四个爬虫,分别从中国金融期货交易所(CFFEX)、上海期货交易所(SHFE)、大连商品期货交易所(DCE)和郑州商品期货交易所(CZCE)官方网站上爬取并整理数据。每个爬虫对应一个类(class):MarketDataFromCFFEXV、MarketDataFromSHFE、MarketDataFromDCE、MarketDataFromCZCE。每个爬虫可以完成网友爬取、数据清洗、数据入库等工作。爬取的数据,可以为以后的品种选择模型等应用提供可靠的数据源。 2.重要的知识 1)如何获取实际的url 2)Python3中的urllib模块 3)Python3的编码和解码 4)正则表达式 5)pyquery模块 6)Python如何和sqlite数据库进行交互 3.如何使用(以DCE为例) 1)爬取某天的数据(用于更新) 首先创建对象:test=MarketDataFromDCE(“2014/10/15”),表示获取2014年10月15日的交易行情数据。初始化对象时,需要传入日期参数,日期参数为字符串类型,且必须写成”2014/10/15”、”2014/01/01”的形式。 获取网页数据:test.GetNeededData()。上面创建的test对象调用GetNeededData()方法来爬取数据,爬取得到的数据放在属性Data中。如果要查看Data,直接打印即可:print(test.Data)。 数据入库:test.InsertDataToDB()。这个方法创建相应的表并把数据插入到该表中。每个交易所对应一个表,同一个交易所的数据放在同一个表中,通过合约名称和日期,可以对每行记录作唯一标识。 2)爬取所有历史数据 (1)首先创建一个交易日期字符串外部文档。 文档每行代表一个交易日: 如:2014-12-10 2014-12-11 2014-12-12 (2)读取交易日期文档到python f=open(r”F:\Python\GetFuturesDataFromExchanges\tradingdate.txt”,”r”); (3)爬取每个交易日数据 for i in f.readlines(): i=i.replace(“\n”,””).strip(); Task=MarketDataFromDCEV3.MarketDataFromDCE(i); Task.InsertDataToDB(); print(“My Host,”+i+” “+”is over”); (4)关闭f对象,释放内存 f.close(); 4.需要注意的地方 1)每个爬虫可能有多个版本,如V1代表版本1,V2代表版本2,高版本是在低版本的基础上改进的,所以使用时只需要用最新的版本即可。 2)可以把这个做成一个package,每个爬虫为一个模块。调用这个包之前,需要设置访问路径,sys.path.append(r”F:\Python\GetFuturesDataFromExchanges”)。 3)使用模块时,注意爬虫类属性saveurl,这个属性用来指定输出数据库的路径。 self.SaveUrl=r”F:\Python\GetFuturesDataFromExchanges\FuturesMarketDataDB.db” 4)上期所数据在2013年10月16日之前是gbk编码;之后是utf-8编码 5)郑期所数据在历史不同时期也有不同的xml结构,因此有一个beta版,现在应该用正常版。 附(完整代码见附件): #!/usr/local/bin/python #-*-coding:utf-8-*- #Get market data from futures exchanges #designed and programed by lianxiangbin(LianZhang,qq785674410) #2014-10-20 import urllib.request import urllib.parse from pyquery import PyQuery import sqlite3 import datetime class MarketDataFromDCE: #define the attributes def __init__(self,date,SaveUrl): self.date=date[0:4]+date[5:7]+date[-2:];#”2014/05/23″ self.url=r”http://www.dce.com.cn/PublicWeb/MainServlet”; self.PostDic={‘action’:’Pu00011_result’,’Pu00011_Input.trade_date’:self.date, ‘Pu00011_Input.trade_type’:’0′,’Pu00011_Input.variety’:’all’, ‘Submit’:u’查 询’} #print(self.PostDic) self.Rename={‘大豆’:’a’,’豆二’:’b’,’豆粕’:’m’,’豆一’:’a’,’豆油’:’y’,’鸡蛋’:’jd’,\ ‘焦煤’:’jm’,’焦炭’:’j’,’玉米’:’c’,’胶合板’:’bb’,’聚丙烯’:’pp’,’聚乙烯’:’l’,’铁矿石’:’i’,’纤维板’:’fb’,’棕榈油’:’p’,’聚氯乙烯’:’v’}; self.SaveUrl=SaveUrl; self.Data={}; #get the html page def GetWebPage(self): PostDicDecoded=urllib.parse.urlencode(self.PostDic).encode(encoding=’gbk’); Request=urllib.request.Request(self.url,PostDicDecoded); MyPage=urllib.request.urlopen(Request).read().decode(“gbk”,”ignore”); if not MyPage: print(“Dear Host,I can not find the web page”); return MyPage; #this is the trading date def GetTheTradingDay(self): TradingDay=datetime.datetime(int(self.date[0:4]),int(self.date[4:6]),int(self.date[-2:])); return TradingDay; #Get the data we needed from the origin file def GetNeededData(self): MyPage=self.GetWebPage(); TradingDay=self.GetTheTradingDay(); Contents=PyQuery(MyPage); #print(Contents); A=Contents(“table”).eq(1); A=PyQuery(A); for tr in A(“tr”): Contrasts=[]; values=[TradingDay]; for i in range(len(tr)): data=PyQuery(tr).find(“td”).eq(i).text(); if i<2: Contrasts.append(data); if i==0: Symbol=Contrasts[0]; if Symbol.strip() in self.Rename: Symbol=self.Rename[Symbol]; values.append(Symbol); else: values.append(data); key=Contrasts[0]+Contrasts[1]; if (u”商品名称” in key) or (u”小计” in key) or (u”总计” in key): continue; values[1:]=[element.replace(“,”,””).replace(“-“,””).strip() for element in values[1:]]; self.Data.setdefault(key,values); #Insert into DB def InsertDataToDB(self): self.GetNeededData(); conna=sqlite3.connect(self.SaveUrl); #if conna: # print(“database is successfully connected”); cursor=conna.cursor(); SQLquery1=”create table if not exists DCE(Contracts varchar(20),date datetime,Symbol nvarchar(30),Open numeric(15,2),\ High numeric(15,2),Low numeric(15,2),Close numeric(15,2),PreSettlement numeric(15,2),Settlement numeric(15,2),\ Change1 numeric(15,2),Change2 numeric(15,2),Volume numeric(25,2),OpenInt numeric(25,2),\ ChangeofOpenInt numeric(25,2),Turnover numeric(30,2))”; cursor.execute(SQLquery1); for key,value in self.Data.items(): Iter=(key,value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7],value[8],value[9],value[10],value[11],value[12],value[13]); #print(Iter); SQLquery2=”insert into DCE”+” “+”values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)”; cursor.execute(SQLquery2,Iter); conna.commit(); conna.close(); if __name__==”__main__”: try: test=MarketDataFromDCE(“2014/10/15”); test.InsertDataToDB(); except Exception as e: print(“something wrong”) print(e); |