- 银行间的资金流转数额通常非常大,某个银行在遇到资金流转问题时通常会向同业进行拆借,以弥补资金缺口,通常短时间内就会还清。还钱除了还本付息,而用于计算利息的利率,国内最常用的是上海银行间同业拆放利率(Shanghai Interbank Offered Rate,简称Shibor),它是由信用等级较高的银行组成报价团自主报出的人民币同业拆出利率计算确定的算术平均利率。简单来说,它披露的是银行间互相借钱的利率。这个利率还能帮助一些资管类金融机构制定报价标准,如制定某种理财产品的收益率等。
- 本节目标就是爬取下图所示的网页(http://www.shibor.org)中不同期限的利率,其中O/N表示隔夜拆借利率(即当天借第二天还),1W表示1周利率,1M表示1月利率,1Y表示1年利率,其余依此类推。
1.爬取方法1:用switch_to.frame()函数切换到子网页
(1)获取网页源代码
from selenium import webdriver
browser = webdriver.Chrome()
url = 'http://www.shibor.org/'
browser.get(url)
data = browser.page_source
- 打印输出网页源代码,在其中搜索在模拟浏览器中看到的某个利率值,会发现搜索不到。这是因为利率信息实际上位于
<iframe> 标签定义的子网页中,即在http://www.shibor.org这个父网页用<iframe> 标签嵌套了一个子网页。而Selenium库中打开网址http://www.shibor.org后,默认是在父网页里操作,无法直接获取子网页的信息。而要在获取子网页中的信息,需要用switch_to.frame()函数来切换子网页。 - 用开发者工具查看利率信息的表格,可以看到的确位于一个
<iframe> 标签中,而且<iframe> 标签不是一个新的HTML文件的完整代码,即在该父网页中嵌套了一个子网页,如下图所示。这里<iframe> 标签的name属性值在之后会用到。 - 有了
<iframe> 标签的name属性(volume10BondDealQuotesEN)后,就可以用switch_to.frame()函数切换到该子网页了,代码如下:
browser.switch_to.frame('volume10BondDealQuotesEN')
data = browser.page_source
- 打印出此时获取的网页源代码data,会发现里面已经含有要爬取的利率值了。
- 获取网页源代码的完整代码:
from selenium import webdriver
browser = webdriver.Chrome()
url = 'http://www.shibor.org/'
browser.get(url)
browser.switch_to.frame('volume10BondDealQuotesEN')
data = browser.page_source
print(data)
(2)提取表格中的数据
- 获取网页的源代码后,利用pandas库(第6章会详细讲解)快速提取网页中的表格数据,代码如下:
from selenium import webdriver
browser = webdriver.Chrome()
url = 'http://www.shibor.org/'
browser.get(url)
browser.switch_to.frame('volume10BondDealQuotesEN')
data = browser.page_source
import pandas as pd
table = pd.read_html(data)
df = table[3]
df
- 第12行代码用pandas库中的read_html()函数提取网页中的所有表格,返回的是一个列表,列表中的每一个元素对应一个表格。
- 通过尝试,发现要爬取的利率值位于第4张表格(即序号为3的元素),因此在第3行代码用table[3]来提取。
- 在Jup中打印出df,结果如下图所示。可以看到表格一共有5列(最左侧的序号是行索引,不属于表格列),其中第2,、3、5列是所需内容。此外,这里的表头(即列名)也需要调整。
- 通过如下代码可以提取所需列并修改列名:
from selenium import webdriver
browser = webdriver.Chrome()
url = 'http://www.shibor.org/'
browser.get(url)
browser.switch_to.frame('volume10BondDealQuotesEN')
data = browser.page_source
import pandas as pd
table = pd.read_html(data)
df = table[3]
df = df[[1,2,4]]
df.columns = ['期限','Shibor(%)','涨跌(BP)']
df
- 在jup中打印输出处理后的df,结果如下图所示。
- 假设现在需要知道3月(3M)利率减去1月利率的差,代码如下:
from selenium import webdriver
browser = webdriver.Chrome()
url = 'http://www.shibor.org/'
browser.get(url)
browser.switch_to.frame('volume10BondDealQuotesEN')
data = browser.page_source
import pandas as pd
table = pd.read_html(data)
df = table[3]
df = df[[1,2,4]]
df.columns = ['期限','Shibor(%)','涨跌(BP)']
M_1 = df[df['期限'] == '1M']['Shibor(%)']
M_3 = df[df['期限'] == '3M']['Shibor(%)']
diff = float(M_3) - float(M_1)
diff = round(diff,3)
diff
- df[df[‘期限’] == ‘1M’]表示筛选出"期限"列中值为"1M"的行,然后通过[‘Shibor(%)’]在筛选出的行中提取“Shibor(%)”列的数值,即1月的利率。
0.058
补充知识点:浏览器同级页面切换–switch.window()函数
- 在爬虫实战中,除了需要在父网页中切换到子网页,有时还需要在浏览器的同级页面间切换。例如,用Selenium库在百度新闻中模拟搜索新闻后,模拟单击一个新闻链接,会弹出一个新窗口显示该新闻的详情页面,如下图所示。此时用browser.page_source获取的仍然是原窗口中页面(搜索结果页面)的网页源代码,而不是新窗口中页面(新闻详情页面)的网页源代码。要获取新窗口中页面的内容,需在窗口之间进行切换。
- 窗口切换的具体方法为:先用window_handles属性获取浏览器所有窗口的句柄(可以将句柄理解为各个浏览器窗口的身份识别)集合,再用switch_to.window()函数根据句柄切换到对应的窗口。演示代码如下:
handles = browser.window_handles
browser.switch_to.window(handles[0])
browser.switch_to.window(handles[-1])
- 回到前面百度新闻的例子,要获取模拟单击链接打开的新闻详情页面源代码,可以使用如下代码:
from selenium import webdriver
browser = webdriver.Chrome()
url = 'https://www.baidu.com/s?rtt=1&bsst=1&cl=2&tn=news&ie=utf-8&word=阿里巴巴'
browser.get(url)
browser.find_element_by_xpath('//*[@id="1"]/div/h3/a').click()
handles = browser.window_handles
browser.switch_to.window(handles[-1])
data = browser.page_source
print(data)
2.爬取方法2:直接找到子网页的实际地址
- 除了用switch_to.frame()函数切换到子网页,本案例还有其他解决办法:直接找到子网页的实际网址,再获取网页源代码。
- 用开发者工具观察父网页的源代码,可以发现在
<iframe> 标签最后有一个src属性,找到网址“https://www.chinamoney.com.cn/r/cms/chinese/chinamoney/html/shiborOrg/shibor.html”,可用于爬取数据。 - 找到子网页的世界网址后,就可以通过如下代码快速获取子网页的源代码:
from selenium import webdriver
browser = webdriver.Chrome()
url_2 = 'https://www.chinamoney.com.cn/r/cms/chinese/chinamoney/html/shiborOrg/shibor.html'
browser.get(url_2)
data = browser.page_source
import pandas as pd
table = pd.read_html(data)
df = table[3]
print(df)
- 注意,如果以上代码得到爬取方法1的结果,可以将3-4行代码的注释去掉。通过Selenium库先访问父网页http://www.shibor.org,再访问子网页https://www.chinamoney.com.cn/r/cms/chinese/chinamoney/html/shiborOrg/shibor.html。
|