资讯专栏INFORMATION COLUMN

运用Python网络爬虫抓取金融衍生品数据库的经典案例

89542767 / 673人阅读

  从行业角度来说,通过一步一步剖析,目标就是简易,新手入门requests网络爬虫及新手入门pandas数据剖析就能完成,文中关键为大家介绍Python网络爬虫抓取金融衍生品数据库的经典案例,感兴趣的小伙伴一起了解一下吧


  哈喽大家好政胤今日教给大家抓取金融衍生品数据和信息


  每日任务介绍

01.png

  最先,顾客原消费是获得https://hq.smm.cn/copper网站里的价钱数据和信息(注:获得的是平台上的公开数据),如图所示:


  若以此网站为主要目标,就需要解决问题是“登陆”客户,然后将价钱剖析为报表开展导出就可以。可是,事实上顾客主要目标是获得“沪铜CU2206”的历史价格查询,尽管此网站也是有给出的数据,但需要“VIP”才能够浏览,而VIP必须充钱...


  数据的价值!!!


  因为,客户满意度仅仅只是“沪铜CU2206”一种期货历史价格查询,充钱VIP性价比低,因而,具体的目标和任务变成怎样获得的历史价格查询,总体目标变成各大网站有发布给出的数据的网站地址。而最终解决此问题,是有求于无所不能的搜索引擎^_^。发现了适宜的网址,且读取数据难度系数也基本降到最低标准难度系数。

02.png

  处理流程


  1.网页搜索网络资源:这一步是所有每日任务完备的最难题(详细不会太难),但是这里卖个关子,全篇不发布最后寻找网站,大伙儿试一试能不能获取到,及其耗费多久^_^。


  2.解析网站要求,最后寻找网站经剖析后,发觉读取数据可以通过get的方法递交主要参数。而要求的主要参数如下所示:/price?starttime=1638545822&endtime=1654357022&classid=48,看了就知有起始时间、截止时间的时间格式,及其商品id。再剖析headers,竟然连cookie都不用,表明并没有流量劫持!并没有流量劫持!并没有流量劫持!不得不承认人品大爆发!


  3.剖析回应数据和信息:因为回应信息是整齐的json格式数据和信息,使用pandas的read_json立即可以获得dataframe格式的信息,该流程也从未有过难度系数。


  代码编写


  #author:zheng yin
  #contact:1278420339 qq.com
  """
  1.这是爬取沪铜的程序
  2.该网站沪铜当月的数据实际请求地址是:'(实际网址)/price?starttime={starttime}&endtime={endtime}&classid={classid}'
  2.1.starttime为起始日期的时间戳
  2.2.endtime为结束日期的时间戳
  2.3.classid为查询商品的id
  3.该网址可以直接发起请求获取数据
  我是政胤期待你的关注
  """
  import time
  from datetime import datetime
  import pathlib as pl
  import requests
  import pandas as pd
  class Spider:
  """
  爬取网站数据的爬虫对象
  """
  def __init__(self,starttime:str=None,endtime:str=None,classid:int=48):
  """
  初始化对象属性
  :param starttime:数据的起始日期,文本日期格式,示例2022-1-1
  :param endtime:数据的结束日期,文本日期格式,示例2022-1-1
  :param classid:商品id,默认48
  """
  self.classid=classid#商品id
  self.data=pd.DataFrame()#初始化空dataframe
  self.data_file=pl.Path('./data/hutong.xlsx')#爬取的数据存储文件
  #列名字典
  self.cols_dict={
  'createtime':'日期',
  'classid':'商品',
  'start':'开盘',
  'end':'收盘',
  'min':'最低',
  'max':'最高',
  'move':'涨跌',
  'move_percent':'涨跌百分比'
  }
  #商品id字典
  self.classid_dict={
  48:'CU2206'
  }
  #获取爬取的开始时间与结束时间
  self.starttime,self.endtime=self.make_starttime_endtime(starttime=starttime,endtime=endtime)
  #初始化需要爬取的url
  self.url='(实际地址)/price?starttime={starttime}&endtime={endtime}&classid={classid}'
  #初始化headers
  self.headers={
  'User-Agent':'Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko)Chrome/99.0.4844.51 Safari/537.36',
  'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
  'Accept-Encoding':'gzip,deflate,br',
  'Accept-Language':'zh-CN,zh;q=0.9',
  }
  def make_starttime_endtime(self,starttime:str,endtime:str):
  """
  制作起始日期,逻辑如下;
  1.如果有传入日期,则根据传入的日期,定义起始日期与结束日期
  2.如果未传入参数,则根据读取到的历史数据文件中的最大日期作为起始日期、以当前日期为结束日期
  3.如果未读取到历史数据文件,或文件中的最大日期为空,则以2021-1-1作为起始日期,以当前日期作为结束日期
  :param starttime:数据的起始日期,文本日期格式,示例2022-1-1
  :param endtime:数据的结束日期,文本日期格式,示例2022-1-1
  :return:
  """
  self.read_data()#读取历史爬取数据
  now=datetime.now()#获取当前时间的时间戳整数部分
  if endtime:#如果非空
  year,month,day=endtime.split('-')
  endtime=int(now.replace(year=int(year),month=int(month),day=int(day)).timestamp())
  else:
  endtime=int(now.timestamp())
  if starttime:
  year,month,day=starttime.split('-')
  starttime=int(now.replace(year=int(year),month=int(month),day=int(day)).timestamp())
  else:
  starttime=self.data['日期'].max()
  if pd.isnull(starttime):#如果开始日期是空值
  starttime=int(now.replace(year=2021,month=1,day=1).timestamp())
  else:
  starttime=int(
  now.replace(year=starttime.year,month=starttime.month,day=starttime.day).timestamp())
  return starttime,endtime
  def read_data(self):
  """
  读取历史数据
  :return:
  """
  if self.data_file.is_file():#如果历史数据文件存在
  self.data=pd.read_excel(self.data_file)
  self.data['日期']=self.data['日期'].map(lambda x:x.date())
  else:#如果历史数据文件不存在,那么初始化一个只有列名的dataframe,
  self.data=pd.DataFrame(self.cols_dict.values()).set_index(0).T
  def crawl_data(self):
  """
  爬取数据
  :return:
  """
  retry_times=0
  while retry_times<10:#重试10次
  try:
  res=requests.get(
  self.url.format(starttime=self.starttime,endtime=self.endtime,classid=self.classid),
  headers=self.headers,timeout=30)
  if res.status_code==200:#如果返回状态至为200,进行后续数据加工
  data=pd.read_json(res.text)#json格式转换为dataframe
  data['createtime']=data['createtime'].map(lambda x:datetime.fromtimestamp(x).date())#时间戳日期转换为日期
  data.rename(columns=self.cols_dict,inplace=True)#重命名列
  data=data[self.cols_dict.values()]#截取需要的列
  data['商品']=self.classid_dict.get(self.classid,'未知商品,请维护classid_dict字典')#转换商品名
  data.sort_values(by=['商品','日期'],ascending=True,inplace=True)#按日期升序排序
  return data
  else:
  retry_times+=1
  print(f'返回状态码是{res.status_code},等待5秒后重新发起请求')
  time.sleep(5)
  except Exception as e:
  retry_times+=1
  print(f'请求发生错误,等待5秒后重新发起请求,错误信息:{e}')
  time.sleep(5)
  print('发起10次请求均未能获得数据')
  return pd.DataFrame()
  def concat_and_write_data(self,data:pd.DataFrame):
  """
  合并数据,并将数据写入文件
  :param data:传入需要合并的数据
  :return:
  """
  self.data=pd.concat([self.data,data])#合并数据
  self.data=self.data.drop_duplicates(['日期','商品'],keep='last')#数据根据商品名称与日期进行去重,每次保留最新的记录
  if not self.data_file.parent.is_dir():#检查数据文件的目录是否存在,如不存在则创建新目录
  self.data_file.parent.mkdir()
  self.data.to_excel(self.data_file,index=False,encoding='utf-8')#输出数据为excel格式
  def run(self):
  """
  运行程序
  :return:
  """
  data=spider.crawl_data()#运行爬取
  if len(data)>0:#如果爬取到的数据不为空
  self.concat_and_write_data(data)
  start=str(datetime.fromtimestamp(self.starttime))[:10]
  end=str(datetime.fromtimestamp(self.endtime))[:10]
  print(f'{start}至{end}数据爬取任务完成')
  def pivot_data(self):
  """
  将数据转换为透视表式的格式
  :return:
  """
  data=self.data.copy()
  data['年月']=data['日期'].map(lambda x:f'{str(x)[:7]}')
  data['日']=data['日期'].map(lambda x:x.day)
  data=data.pivot_table(values='收盘',index='日',columns='年月',aggfunc='sum')
  data_mean=data.mean().to_frame().T
  data_mean.index=['平均值']
  data=pd.concat([data,data_mean])
  data.to_excel(self.data_file.parent.parent/'data.xlsx',encoding='utf-8')
  if __name__=='__main__':
  spider=Spider()
  spider.run()
  spider.pivot_data()
  print(spider.data)


  因为网址并没有流量劫持,且主要参数简易,事实上任务通常是整体规划一下下怎样设计增量同步数据和信息的操作流程,详细编码如下所示:


  汇总


  从行业角度来说,通过一步一步剖析,目标就是简易,新手入门requests网络爬虫及其新手入门pandas数据剖析就能完成(唯一难度系数在找到更好的总体目标)。可是换一个角度,从经济效益来说,也是非常有用的,即减少了某网站高额的服务年费(注:也不是说服务年费不值,仅仅局限于要求仅仅只是CU2206一种数据和信息处时,性价比高过低),同时也防止了人工控制的繁杂,及其由此产生的不正确。用极小的培训成本就可以解决极大地难题


  综上所述,这篇文章就给大家解答到这里了,希望可以给大家带来帮助。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128853.html

相关文章

  • 为什么去中心化兑换协议很重要

    摘要:此外,还有一类行为,只有去中心化兑换协议才能做到。最后,去中心化兑换协议可以立刻自动支持新的代币。去中心化兑换要求用户管理自己基金的安全性,而相关工具目前尚不成熟。 原文:https://medium.com/@FEhrsam/w... 今天,去中心化兑换(decentralized exchange)仍处于早期,但是几年后,它很可能会是区块链生态中不可或缺的一环。 首先,去中心化兑...

    Olivia 评论0 收藏0
  • 研究人员:云相互依存可能导致“云崩溃”

    摘要:补充说,每一个这类不同的云组件通常都是由单独的一家公司来维护和部署的,出于竞争的考虑,这些公司往往会尽可能少地披露其服务的内部运营细节。是下周将在波士顿召开的更大范围的展会的一个分会场。 当云计算越来越成为主流之时,各种严重的运营崩溃事故就可能出现,因为在云中,终端用户和厂商的各种东西都在一起混搭、匹配或捆绑着,这就是一位研究人员所撰写的一篇新论文的主张,该论文将在下周于美国波士顿召开的U...

    B0B0 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<