最近日元下滑想趁低点屯一些,但手机银行动不动就要验证密码,每次进结售汇还要阅读30秒购汇申请书,太麻烦了。而网页版的外汇,加载比较慢,偶现访问不了,想找个办法,能快速查询外汇价格。
首先打开建行外汇↓的网页
然后使用f12打开开发者模式,切换到网络-选择Fetch/Xhr,我们发现里面有好几个xml文件
其中有一个叫做jshckpj_new.xml的文件,就是结售汇的xml
我们打开这个文件的标头,访问请求网址会发现数据都储存在里面。
接着我们观察这个xml文件,发现结构比较简单,每个ReferencePriceSettlement展示一个货币的内容。以第一个展示举例:
<ReferencePriceSettlement name="1">
<Ofrd_Ccy_CcyCd>840</Ofrd_Ccy_CcyCd> //此行表示目标货币码
<Ofr_Ccy_CcyCd>156</Ofr_Ccy_CcyCd> //此行表示待兑换的货币码,也就是人民币码
<BidRateOfCash>7.1908</BidRateOfCash> //现钞买入价
<OfrRateOfCash>7.2735</OfrRateOfCash> //现钞卖出价
<BidRateOfCcy>7.2423</BidRateOfCcy> //现汇买入价
<OfrRateOfCcy>7.2735</OfrRateOfCcy> //现汇卖出价
<HBBnk_Bss_Buy_Prc>7.25480000</HBBnk_Bss_Buy_Prc>
<HBBnk_Bss_Sell_Prc>7.25730000</HBBnk_Bss_Sell_Prc>
<Mdl_ExRt_Prc>7.25610000</Mdl_ExRt_Prc>
<LstPr_Dt>20240618</LstPr_Dt> //日期
<LstPr_Tm>203354</LstPr_Tm> //时间
<ExRt_StCd>2</ExRt_StCd>
</ReferencePriceSettlement>
其他的内容只要取值就可以,只有时间的格式不是标准格式需要处理下。所以代码要处理的内容:
从目标xml取值→处理需要的数据→整理时间格式→加工数据内容→打印
为了完成上面的内容,我们需要导入2个库,分别用于请求数据和解析数据
import requests
import xml.etree.ElementTree as ET
第一步先获取值,这边比较简单,xml没有变动是固定用同一个网址,且没有对访问做处理,所以简单粗暴的获取xml的数据
# 请求XML数据
url = "http://forex1.ccb.com/cn/home/news/jshckpj_new.xml"
try:
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
xml_data = response.text
except requests.exceptions.RequestException as e:
print(f"请求XML数据时发生错误: {e}")
xml_data = ""
第二步整理需要的内容,以日元为例。我只需要日元的现汇买卖价格所以只写了日元的部分,如果你需要更多内容可以结合前面的分析改写。
# 解析XML数据
root = ET.fromstring(xml_data)
# 安全提取更新时间
date_elem = root.find('.//LstPr_Dt')
time_elem = root.find('.//LstPr_Tm')
if date_elem is not None and time_elem is not None:
# 格式化日期和时间
formatted_date = date_elem.text[0:4] + "-" + date_elem.text[4:6] + "-" + date_elem.text[6:8]
formatted_time = time_elem.text[0:2] + ":" + time_elem.text[2:4] + ":" + time_elem.text[4:6]
last_update_time = f"{formatted_date} {formatted_time}"
else:
last_update_time = "未知时间"
# 初始化汇率变量
jpy_bid_rate = None # 日元买入价
jpy_offer_rate = None # 日元卖出价
# 遍历所有的 <ReferencePriceSettlement> 元素
for ref_price in root.findall('ReferencePriceSettlement'):
ofrd_ccy_code = ref_price.find('Ofrd_Ccy_CcyCd').text
ofr_ccy_code = ref_price.find('Ofr_Ccy_CcyCd').text
# 检查是否是日元392对人民币156的汇率
if (ofrd_ccy_code, ofr_ccy_code) == ('392', '156'):
jpy_bid_rate = float(ref_price.find('BidRateOfCcy').text)
jpy_offer_rate = float(ref_price.find('OfrRateOfCcy').text)
# 检查汇率是否已找到
if jpy_bid_rate is not None and jpy_offer_rate is not None:
# 输出标题和更新时间
# 输出汇率
print(
f"日元汇率\n"
f"更新时间:{last_update_time}\n"
f"现汇买入价:{jpy_bid_rate}\n"
f"现汇卖出价:{jpy_offer_rate}"
)
else:
print("未找到日元的汇率信息")
按这样,代码输出的内容为
但是日汇比较小,太多小数点看得不清晰,我们可以先预先计算每5w日元、10万日元的购入价格(这里注意,现汇卖出价是银行的卖出价,也就是用户的购入价,所以计算时应该取现汇卖出价的值进行计算)
# 计算购买5万日元所需的人民币花费
amount_50000_jpy = 50000
cost_50000_jpy_in_cny = amount_50000_jpy * jpy_offer_rate
# 计算购买10万日元所需的人民币花费
amount_100000_jpy = 100000
cost_100000_jpy_in_cny = amount_100000_jpy * jpy_offer_rate
# 打印结果
print(f"购买5万日元所需的人民币花费: {cost_50000_jpy_in_cny:.2f} 元")
print(f"购买10万日元所需的人民币花费: {cost_100000_jpy_in_cny:.2f} 元")
最后附上完整代码以及其他货币码:
import requests
import xml.etree.ElementTree as ET
# 请求XML数据
url = "http://forex1.ccb.com/cn/home/news/jshckpj_new.xml"
try:
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
xml_data = response.text
except requests.exceptions.RequestException as e:
print(f"请求XML数据时发生错误: {e}")
xml_data = ""
# 解析XML数据
root = ET.fromstring(xml_data)
# 安全提取更新时间
date_elem = root.find('.//LstPr_Dt')
time_elem = root.find('.//LstPr_Tm')
if date_elem is not None and time_elem is not None:
# 格式化日期和时间
formatted_date = date_elem.text[0:4] + "-" + date_elem.text[4:6] + "-" + date_elem.text[6:8]
formatted_time = time_elem.text[0:2] + ":" + time_elem.text[2:4] + ":" + time_elem.text[4:6]
last_update_time = f"{formatted_date} {formatted_time}"
else:
last_update_time = "未知时间"
# 初始化汇率变量
jpy_bid_rate = None # 日元买入价
jpy_offer_rate = None # 日元卖出价
# 遍历所有的 <ReferencePriceSettlement> 元素
for ref_price in root.findall('ReferencePriceSettlement'):
ofrd_ccy_code = ref_price.find('Ofrd_Ccy_CcyCd').text
ofr_ccy_code = ref_price.find('Ofr_Ccy_CcyCd').text
# 检查是否是日元826对人民币156的汇率
if (ofrd_ccy_code, ofr_ccy_code) == ('392', '156'):
jpy_bid_rate = float(ref_price.find('BidRateOfCcy').text)
jpy_offer_rate = float(ref_price.find('OfrRateOfCcy').text)
# 检查汇率是否已找到
if jpy_bid_rate is not None and jpy_offer_rate is not None:
# 输出标题和更新时间
# 输出汇率
print(
f"日元汇率\n"
f"更新时间:{last_update_time}\n"
f"现汇买入价:{jpy_bid_rate}\n"
f"现汇卖出价:{jpy_offer_rate}"
)
# 计算购买5万日元所需的人民币花费
amount_50000_jpy = 50000
cost_50000_jpy_in_cny = amount_50000_jpy * jpy_offer_rate
# 计算购买10万日元所需的人民币花费
amount_100000_jpy = 100000
cost_100000_jpy_in_cny = amount_100000_jpy * jpy_offer_rate
# 打印结果
print(f"购买5万日元所需的人民币花费: {cost_50000_jpy_in_cny:.2f} 元")
print(f"购买10万日元所需的人民币花费: {cost_100000_jpy_in_cny:.2f} 元")
else:
print("未找到日元的汇率信息")
978=欧元
840=美元
392=日元
826=英镑
036=澳大利亚元
756=瑞士法郎
124=加拿大元
344=港币
702=新加坡元
208=丹麦克朗
752=瑞典克朗
578=挪威克朗
554=新西兰元
446=澳门元
458=马来西亚林吉特
764=泰铢
710=南非兰特
643=俄罗斯卢布
398=哈萨克斯坦坚伐