原來(lái)那些賺錢的投資者都在用這個(gè)辦法!

近半年多表箭,基金又變得異沉蘖火爆,很多小朋友開始投資基金,但是基金的選擇是個(gè)頭疼的問(wèn)題序目,網(wǎng)上眾多up主臂痕,各自心懷鬼胎、眾說(shuō)紛紜猿涨。之前火爆的“坤坤”握童,一夜之間也跌回解放前。所以叛赚,想賺錢澡绩,還得靠自己,任何人都不會(huì)對(duì)你的選擇負(fù)責(zé)俺附!

最近很流行的一句話:“你只能賺到自己認(rèn)知范圍內(nèi)的錢肥卡。”

那么事镣,自己如何選擇步鉴?

孫子曾經(jīng)曰過(guò):**知己知彼…… **

金選好基友

先看看某寶的“金選好基”:


image.png

再看看已經(jīng)跌下神壇的坤坤的基金在某寶上是個(gè)什么狀態(tài):


image.png

金選!

金牌經(jīng)理璃哟!

驚不驚喜氛琢?意不意外?

所以随闪,平臺(tái)推薦的你敢買嗎阳似?

毛爺爺說(shuō)的好:自己動(dòng)手,豐衣足食铐伴。 基金好不好撮奏,我們自己來(lái)判斷。

自己來(lái)分析基金的好壞当宴,其實(shí)步驟也很簡(jiǎn)單畜吊,類似把大象放進(jìn)冰箱里:

  1. 打開冰箱——獲取數(shù)據(jù)
  2. 把大象塞進(jìn)冰箱——分析數(shù)據(jù)
  3. 關(guān)上冰箱門——買入

1. 獲取數(shù)據(jù)

按照國(guó)際慣例,我們以東方財(cái)富的天天基金網(wǎng)作為數(shù)據(jù)源:

東方財(cái)富網(wǎng)

網(wǎng)上其實(shí)很多教我們?nèi)绾斡胮ython爬天天基金的數(shù)據(jù)的文章即供,很顯然這些文章幫助了很多人定拟,但也給天天基金網(wǎng)造成了不少的困擾,所以他們經(jīng)常修改一些參數(shù)名或者id名逗嫡。

好老師應(yīng)該授人予漁,而非授人予魚株依,文章會(huì)有點(diǎn)長(zhǎng)驱证,我把小白可能遇到的坑以及解題思路都會(huì)盡量詳細(xì)的分享出來(lái),目的就是讓小白真正掌握獲取數(shù)據(jù)的能力恋腕,不管別人的網(wǎng)站再如何變化抹锄,我們都能找到應(yīng)對(duì)的辦法。

數(shù)據(jù)獲取方式

通常來(lái)說(shuō),公開網(wǎng)站的數(shù)據(jù)獲取方式有兩種:

  1. 爬蟲——最簡(jiǎn)單粗暴
  2. Web API——最優(yōu)雅

1.1 爬蟲

爬蟲方式是網(wǎng)上文章最多的伙单,雖然看上去簡(jiǎn)單获高,但很多經(jīng)常被爬的網(wǎng)站都會(huì)設(shè)計(jì)一些反爬機(jī)制,小白在實(shí)際操作時(shí)卻會(huì)遇到無(wú)數(shù)的坑吻育∧钛恚坑有很多種:

  1. 反DDOS
  2. 異步加載數(shù)據(jù)
  3. 用戶真實(shí)性驗(yàn)證
    我們先把坑的事情放一邊,回到爬蟲本身布疼,看看如何展開接下來(lái)的工作摊趾。

想爬數(shù)據(jù),第一步就是分析頁(yè)面的代碼游两,打開瀏覽器的開發(fā)者模式砾层,選擇頁(yè)面中數(shù)據(jù)的部分,然后分析其HTML代碼的特征:


以上圖為例贱案,所有的數(shù)據(jù)都在 <table id="dbtable">...</table> 標(biāo)簽中肛炮。id在一個(gè)html頁(yè)面中是唯一的,因此通過(guò)代碼只要提取出id=“dbtable”的對(duì)象宝踪,理論上就可以得到table中的所有數(shù)據(jù)了侨糟。

但是,眾所周知肴沫,事情總不會(huì)一帆風(fēng)順粟害,不過(guò),我先上一段代碼吧:

import requests
url = 'http://fund.eastmoney.com/data/fundranking.html#tgp;c0;r;s1nzf;pn50;ddesc;qsd20200715;qed20210715;qdii;zq;gg;gzbd;gzfs;bbzt;sfbb'
# 獲取url的結(jié)果
response = requests.get(url)
# 看看我們都拿到了什么東西
print(response.content)

以下是結(jié)果的局部:

b'\xef\xbb\xbf\r\n\r\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n<html xmlns="http://www.w3.org/1999/xhtml">\r\n<head>\r\n    <title>\xe5\xbc\x80\xe6\x94\xbe\xe5\xbc\x8f\xe5\x9f\xba\xe9\x87\x91\xe6\x8e\x92\xe8\xa1\x8c _ \xe5\xa4\xa9\xe5\xa4\xa9\xe5\x9f\xba\xe9\x87\x91\xe7\xbd\x91</title>\r\n

是不是看不懂颤芬?不要內(nèi)疚悲幅,我也看不懂,因?yàn)檫@東西本來(lái)就有問(wèn)題站蝠, \xe5\xbc\x80\xe6\x94\xbe\xe5\xbc\x8f\xe5\x9f\這些有規(guī)律但不知所云的東西其實(shí)是中文汰具,只不過(guò)request庫(kù)默認(rèn)的編碼方式是ISO-8859-1,在ISO-8859-1的字符集是不包涵中文的菱魔,所以就把原始信息直接丟了出來(lái)留荔。這是小白們遇到的第一個(gè)小坑——中文字符編碼問(wèn)題。如何解決也非常的簡(jiǎn)單澜倦,只要做一個(gè)decode操作聚蝶,把字符集設(shè)置成utf-8,那么一切都回來(lái)了藻治。不信你就試試看:

print(response.content.decode('utf8'))

# 以下是部分結(jié)果:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>開放式基金排行 _ 天天基金網(wǎng)</title>
    <meta name="keywords" content="基金排行,開放式基金排行,創(chuàng)新基金排行,貨幣基金排行,漲幅排行,基金排行查詢,漲幅分布,自定義基金排行,股票型基金,混合型基金,債券型基金,指數(shù)型基金,保本型基金,QDII,LOF,按基金公司篩選" />
    <meta name="description" content="天天基金網(wǎng)每日及時(shí)更新開放式基金收益率排行碘勉。" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="mobile-agent" content="format=html5; url=https://m.1234567.com.cn/?page=jjph&tab=qb" />
    <meta http-equiv="Content-Language" content="zh-CN" />
    <meta http-equiv="Cache-Control" content="no-cache" />
    <meta http-equiv="Expires" content="-1" />

很明顯,中文正常顯示了桩卵,連換行也正常了验靡。

接下來(lái)的問(wèn)題就是想辦法從這堆html代碼中把<table id="dbtable">...</table> 的內(nèi)容過(guò)濾出來(lái)倍宾。還記得前面截圖中的XPath嗎?

xpath

什么是XPath胜嗓?不知道的看這里高职。

按照最簡(jiǎn)單的做法,看看我們能得到什么辞州,先看代碼:

from lxml import etree
tree = etree.HTML(response.content.decode('utf8'))
dbtab = tree.xpath('//*[@id=\"dbtable\"]')
print(dbtab[0].text)

但是結(jié)果什么都沒(méi)有怔锌。也許這是我們遇到的第二個(gè)坑!回去翻翻print(response.content.decode('utf8'))孙技,找到<table id="dbtable">發(fā)現(xiàn):

<table id="dbtable">
                <thead>
                    <tr>
                        <th>比較</th>
                        <th>序號(hào)</th>
                        <th col="dm" class="tworow"><a><span class="ades">基金<br />
                            代碼</span><span class="showway"></span></a></th>
                        <th col="jc"><a>基金簡(jiǎn)稱</a></th>
                        <th col="jzrq"><a>日期</a></th>
                        <th col="dwjz"><a>單位凈值</a></th>
                        <th col="ljjz"><a>累計(jì)凈值</a></th>
                        <th col="rzdf"><a>日增長(zhǎng)率</a></th>
                        <th col="zzf"><a>近1周</a></th>
                        <th col="1yzf"><a>近1月</a></th>
                        <th col="3yzf"><a>近3月</a></th>
                        <th col="6yzf"><a>近6月</a></th>
                        <th col="1nzf"><a>近1年</a></th>
                        <th col="2nzf"><a>近2年</a></th>
                        <th col="3nzf"><a>近3年</a></th>
                        <th col="jnzf"><a>今年來(lái)</a></th>
                        <th col="lnzf" style="white-space: nowrap;"><a>成立來(lái)</a></th>
                        <th col="qjzf" id="sortclass" class="datespan">
                            <div style="position: relative" col="qjzf">
                                <a onmouseover="show_tip();">自定義</a>
                                <b class="cal" id="calen"></b>
                            </div>
                        </th>
                        <th class="yh_head">手續(xù)費(fèi)</th>
                        <th>
                            <label style="text-align: center; vertical-align: middle">
                                <input id="onlysale" style="margin-top: 0px" type="radio" value="1" name="showsale" class="md" checked="checked" /><span class="md">可購(gòu)</span></label><br />
                            <label style="text-align: center; vertical-align: middle;">
                                <input style="margin-top: 0px" type="radio" value="0" name="showsale" class="md" id="allfund" checked="" /><span class="md">全部</span>
                            </label>
                        </th>
                    </tr>
                </thead>
                <tbody>
                </tbody>
            </table>

只有表頭产禾,tbody竟然是空的,果然牵啦,我們遇到了第二個(gè)坑亚情,數(shù)據(jù)異步加載。

雖然這是個(gè)坑哈雏,但有好也有壞楞件,通常我們有兩個(gè)解題思路:

  1. 順著爬蟲思路往下走,我們需要一個(gè)瀏覽器的模擬器裳瘪,拿到瀏覽器渲染完成的數(shù)據(jù)土浸。
  2. 既然是異步,那么一定有web API彭羹,這樣我們就不需要用爬蟲爬去數(shù)據(jù)了黄伊,省去了后面繁瑣的數(shù)據(jù)整理工作。

1.1.1 瀏覽器模擬器

本文不作為重點(diǎn)派殷,這里只簡(jiǎn)單介紹一下还最。python生態(tài)的瀏覽器模擬器最有名的就是selinum,它可以調(diào)用本地的瀏覽器驅(qū)動(dòng)毡惜,完整的模擬瀏覽器的操作拓轻,包括點(diǎn)擊事件等,非常強(qiáng)大经伙,在一些需要通過(guò)交互過(guò)程才能獲取到數(shù)據(jù)的場(chǎng)景下非常有用扶叉。

1.2 Web API

既然我們確定了有Web API,那么帕膜,應(yīng)該去哪找它呢枣氧?
首先,還是去看瀏覽器的開發(fā)者工具:


打開Network選項(xiàng)卡垮刹。如果你的選項(xiàng)卡中有一大堆東西作瞄,可以點(diǎn)擊左上角第二排的第二個(gè)按鈕清理一下。接下來(lái)按照下圖的示意危纫,隨便點(diǎn)擊表格上方的分類按鈕,如圖中所示,我點(diǎn)擊的是混合型按鈕:

在下方開發(fā)者工具的列表中多了兩個(gè)請(qǐng)求种蝶,點(diǎn)開最長(zhǎng)的那個(gè)契耿,看到這個(gè)請(qǐng)求的Response中剛好是表格中的內(nèi)容!看來(lái)螃征,這應(yīng)該就是我們要找的東西了搪桂。復(fù)制這個(gè)請(qǐng)求地址:http://fund.eastmoney.com/data/rankhandler.aspx?op=ph&dt=kf&ft=hh&rs=&gs=0&sc=1nzf&st=desc&sd=2020-07-15&ed=2021-07-15&qdii=&tabSubtype=,,,,,&pi=1&pn=50&dx=1&v=0.726345617727655 我們單獨(dú)打開看看:

var rankData ={ErrCode:-999,Data:"無(wú)訪問(wèn)權(quán)限"}

為什么會(huì)這樣?我們也不是注冊(cè)用戶盯滚,打開網(wǎng)頁(yè)就能正程咝担看到數(shù)據(jù)了,哪來(lái)的訪問(wèn)權(quán)限魄藕?

其實(shí)這個(gè)就是網(wǎng)站設(shè)計(jì)的典型反爬機(jī)制内列,也就是前面說(shuō)的第三個(gè)坑,驗(yàn)證用戶的真實(shí)性背率。我簡(jiǎn)單解釋一下背后的邏輯:

一個(gè)正常人類去訪問(wèn)這個(gè)頁(yè)面话瞧,這個(gè)url地址的真正訪問(wèn)者應(yīng)該是http://fund.eastmoney.com/data/fundranking.html 這個(gè)頁(yè)面中的JavaScript代碼,所以它可以通過(guò)驗(yàn)證流量來(lái)源的身份來(lái)確認(rèn)是否是一個(gè)正常訪問(wèn)請(qǐng)求寝姿。

這個(gè)可以偽裝嗎交排?答案是肯定的。為了保持用戶和服務(wù)器端的交互連續(xù)性饵筑,用戶和服務(wù)器之前存在一個(gè)叫做會(huì)話的東西埃篓,在http協(xié)議中叫做request(請(qǐng)求)。request中可以存儲(chǔ)許多與用戶相關(guān)的信息根资,有一些是協(xié)議默認(rèn)的架专,我們還可以在程序里面自定義添加一些特殊信息,實(shí)現(xiàn)從瀏覽器向服務(wù)器傳遞數(shù)據(jù)嫂冻。

注意:通過(guò)URL傳遞參數(shù)的方式是明文的胶征,請(qǐng)勿傳遞敏感信息。這種傳輸方式也叫GET請(qǐng)求桨仿。敏感信息可以采用POST非明文方式睛低,具體方法本文不展開,感興趣的同學(xué)請(qǐng)自行搜索服傍。

說(shuō)到Request钱雷,我們不妨去瀏覽器的開發(fā)者工具中看看剛才的url請(qǐng)求中都有些什么東西:


Request Headers

在請(qǐng)求的Headers里面,我們可以找到Request Headers吹零,我們注意看里面的Host和Referer這兩個(gè)字段罩抗,它倆其實(shí)就是前面說(shuō)的web API去驗(yàn)證請(qǐng)求來(lái)源的依據(jù),我們只要把和兩個(gè)東西塞到我們的Request Header中灿椅,應(yīng)該就能拿到數(shù)據(jù)了套蒂。來(lái)看看代碼:

headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
        'Host': 'fund.eastmoney.com',
        'Accept-Encoding': 'gzip, deflate',
        'Referer': 'http://fund.eastmoney.com/data/fundranking.html'
    }
response = requests.get(url, headers=headers)

我們?cè)黾恿艘粋€(gè)叫做headers的字典钞支,把剛才瀏覽器的Request Headers中的關(guān)鍵內(nèi)容塞進(jìn)去就行,User-Agent和Cookie也可以塞進(jìn)去操刀,一般這種API還會(huì)去校驗(yàn)這兩個(gè)東西烁挟。
偽裝的Header做好了以后,我們?cè)趓equests.get方法中傳入剛才做好的headers骨坑,這樣就能拿到真正的數(shù)據(jù)了:

var rankData = {datas:["000209,信誠(chéng)新興產(chǎn)業(yè)混合,XCXXCYHH,2021-07-16,4.6530,4.6530,-1.81,1.35,35.38,68.71,53.97,153.16,301.12,277.07,60.84,365.30,2013-07-17,1,142.1564,1.50%,0.15%,1,0.15%,1,157.36",
"002190,農(nóng)銀新能源主題,NYXNYZT,2021-07-16,3.8259,3.8259,-3.01,0.54,25.48,53.12,36.05,140.99,352.02,288.26,37.18,282.59,2016-03-29,1,138.3444,1.50%,0.15%,1,0.15%,1,268.34",
"400015,東方新能源汽車混合,DFXNYQCHH,2021-07-16,4.1490,4.6090,-3.93,-0.55,33.22,70.17,42.06,135.85,278.83,221.85,47.79,453.21,2011-12-28,1,136.1310,1.50%,0.15%,1,0.15%,1,164.20",
"001951,金鷹改革紅利混合,JYGGHLHH,2021-07-16,3.3520,3.3520,-3.12,0.06,23.37,48.85,44.05,125.57,224.18,243.79,52.36,235.20,2015-12-02,1,119.8221,1.50%,0.15%,1,0.15%,1,209.80",
……
"700003,平安策略先鋒混合,PACLXFHH,2021-07-16,5.3350,5.4350,0.40,2.18,33.98,61.28,37.01,82.77,208.03,233.65,42.91,483.74,2012-05-29,1,71.7518,1.50%,0.15%,1,0.15%,1,180.64"],
allRecords:4476,
pageIndex:1,
pageNum:50,
allPages:90,
allNum:8252,
gpNum:1610,
hhNum:4476,
zqNum:1983,
zsNum:1164,
bbNum:0,
qdiiNum:183,
etfNum:0,
lofNum:330,
fofNum:169
};

看起來(lái)這是我們要的數(shù)據(jù)了撼嗓,但這個(gè)數(shù)據(jù)還不能被python直接識(shí)別到,因?yàn)榍懊嬗幸欢?*var rankData = * 的鬼東西欢唾。這個(gè)東西是js代碼且警,對(duì)他們網(wǎng)站的前端游泳,但是對(duì)我們毫無(wú)意義礁遣。仔細(xì)分析一下拿到的數(shù)據(jù)發(fā)現(xiàn)斑芜,我們需要的其實(shí)是datas后面的 [ …… ] 里面的東西。數(shù)據(jù)的最后面還有一段allRecords:4476,pageIndex:1,pageNum:50,allPages:90,allNum:8252,gpNum:1610,hhNum:4476,zqNum:1983,zsNum:1164,bbNum:0,qdiiNum:183,etfNum:0,lofNum:330,fofNum:169亡脸。這些是一些參數(shù)值押搪,后面我們都用得著,所以我們干脆把 {……}都弄出來(lái)浅碾,這個(gè)結(jié)構(gòu)和python中的dict結(jié)構(gòu)是一樣的大州。所以,我們只需要把前面的 “var rankData =”去掉就好了垂谢,來(lái)看代碼:

# 截取第14個(gè)字符到倒數(shù)第一個(gè)字符之間的所有內(nèi)容厦画,注意,最后還有一個(gè);號(hào)也要去掉
js_data = response.text[14:-1]

# 把得到的{···}轉(zhuǎn)成dict對(duì)象滥朱。這里我們用到了第三方庫(kù)execjs根暑,沒(méi)有的同學(xué)自己pip install一下
dt = execjs.eval(js_data)

到這里,我們才算真正白嫖到了網(wǎng)站的數(shù)據(jù)徙邻。那么有了數(shù)據(jù)排嫌,接下來(lái)就是分析了。Python以爬蟲和數(shù)據(jù)分析著稱缰犁,而說(shuō)到數(shù)據(jù)分析淳地,必須提到的就是無(wú)所不能的pandas庫(kù)。那么接下來(lái)就來(lái)教大家如何用pandas進(jìn)行數(shù)據(jù)分析帅容。


2. 分析數(shù)據(jù)

前文我們已經(jīng)拿到了網(wǎng)站數(shù)據(jù)并且放到了一個(gè)叫做dt的字典中颇象。但是真正我們需要的數(shù)據(jù)在dt的一個(gè)叫做datas的字段中,這個(gè)數(shù)據(jù)是一個(gè)數(shù)組并徘,我們只需要把它取出來(lái)丟給pandas就可以了遣钳,代碼也非常的簡(jiǎn)單:

import pandas as pd
em_data = pd.DataFrame(dt['datas'])

來(lái)看看我們得到的DataFrame是什么樣的

em_data

很奇怪,數(shù)據(jù)的行數(shù)沒(méi)問(wèn)題麦乞,但是只有一列蕴茴,這是什么原因劝评?先回去看看拿到的數(shù)據(jù):

"000209,信誠(chéng)新興產(chǎn)業(yè)混合,XCXXCYHH,2021-07-16,4.6530,4.6530,-1.81,1.35,35.38,68.71,53.97,153.16,301.12,277.07,60.84,365.30,2013-07-17,1,142.1564,1.50%,0.15%,1,0.15%,1,157.36",
"002190,農(nóng)銀新能源主題,NYXNYZT,2021-07-16,3.8259,3.8259,-3.01,0.54,25.48,53.12,36.05,140.99,352.02,288.26,37.18,282.59,2016-03-29,1,138.3444,1.50%,0.15%,1,0.15%,1,268.34"

為了方便,我截取了前面兩條數(shù)據(jù)荐开,并且做了換行處理付翁。我們看到,每條數(shù)據(jù)都被一對(duì)“”引號(hào)包起來(lái)了晃听,這是一個(gè)二維數(shù)組結(jié)構(gòu),但是pandas無(wú)法直接識(shí)別出來(lái)砰识,不過(guò)也不麻煩能扒,我們只需要做一個(gè)小小的處理就可以——對(duì)這個(gè)字段做分隔符的拆分即可:

# DataFrame的str可以自動(dòng)對(duì)每行的數(shù)據(jù)進(jìn)行處理
em_data = pd.DataFrame(dt['datas'])[0].str.split(',', expand = True)

# 字段拆分完畢后,為了便于分析辫狼,我們需要給它加上字段名初斑,以下是我不辭辛苦一個(gè)個(gè)對(duì)出來(lái)的,拿走不謝~  
cols=['代碼', '名稱', '簡(jiǎn)稱', '日期','單位凈值','累計(jì)凈值','日增長(zhǎng)率','近1周','近1月','近3月','近6月','近1年','近2年','近3年','今年來(lái)','成立來(lái)', '成立日期','自定義', 'A', 'B', '手續(xù)費(fèi)', 'C', 'D', 'E', 'F']
em_data.columns = cols

這樣我們就得到了一個(gè)完美的DataFrame:

至于后面如何進(jìn)行分析膨处,就完全是個(gè)人主觀的事情了见秤,這個(gè)必須自己去學(xué)習(xí)金融知識(shí)和統(tǒng)計(jì)學(xué)知識(shí),一點(diǎn)點(diǎn)積累真椿,技術(shù)部分自己去看pandas的文檔即可鹃答,你能知道的計(jì)算方法pandas都有現(xiàn)成的函數(shù)可以直接使用,非常的強(qiáng)大突硝。

不過(guò)测摔,在拿到一個(gè)數(shù)據(jù)的初期,我喜歡先對(duì)數(shù)據(jù)進(jìn)行一個(gè)整體的了解解恰,做一個(gè)overview锋八,這里強(qiáng)烈安利一個(gè)基于pandas的庫(kù),可以幫助我們進(jìn)行數(shù)據(jù)探索——pandas_profiling护盈,使用也非常非常簡(jiǎn)單:

import pandas_profiling
pandas_profiling.ProfileReport(df)

如果你使用Jupyter Notebook編寫代碼挟纱,那么經(jīng)過(guò)短暫的等待,你就會(huì)看到一個(gè)非常驚人的交互式報(bào)告:




One more thing:優(yōu)化

到這里腐宋,基本技能已經(jīng)介紹完了紊服,但細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),里面隱藏了一個(gè)小問(wèn)題脏款,就是數(shù)據(jù)量的問(wèn)題围苫。我們從開發(fā)者工具中拿到的那個(gè)url只返回了50條數(shù)據(jù),但是一共有幾千個(gè)基金撤师,這么多數(shù)據(jù)我們應(yīng)該怎么燃粮?如果每次只能取50條剃盾,5000條數(shù)據(jù)我們就要取100次腺占,不光速度慢淤袜,而且很有可能被對(duì)方的安全設(shè)備識(shí)別為DDOS攻擊。那么衰伯,有沒(méi)有更佳優(yōu)雅的解決方案呢铡羡?

還記得我們前面提過(guò)的Request參數(shù)傳遞的事情嗎?我們來(lái)分析一下這個(gè)接口的URL地址意鲸,看看能有什么發(fā)現(xiàn):

# 我把它簡(jiǎn)單處理一下烦周,在&符號(hào)后面加上換行,得到了這個(gè)東西怎顾,:
http://fund.eastmoney.com/data/rankhandler.aspx?
op=ph&
dt=kf&
ft=hh&
rs=&
gs=0&
sc=1nzf&
st=desc&
sd=2020-07-15&
ed=2021-07-15&
qdii=&
tabSubtype=,,,,,&
pi=1&
pn=50&
dx=1&
v=0.726345617727655

簡(jiǎn)單解釋一下读慎,url中的“?”號(hào)后面是請(qǐng)求的參數(shù),多個(gè)參數(shù)用&符號(hào)進(jìn)行連接槐雾。
根據(jù)參數(shù)值我們可以簡(jiǎn)單得到以下猜測(cè):

  • sd:start date 開始日期
  • ed:end date 結(jié)束日期
  • pi:page index 所在分頁(yè)的頁(yè)數(shù)
  • pn:page number 每頁(yè)的數(shù)量
    剩下的參數(shù)感興趣的同學(xué)可以自己去研究夭委,pi和pn應(yīng)該就是我們可以利用的地方。如果pn沒(méi)有上限限制募强,那么我們就可以一次性拿到所有的數(shù)據(jù)了株灸,我測(cè)試了4476,也就是所有的混合基金的數(shù)量擎值,順利拿到了所有的數(shù)據(jù)慌烧。
    既然,我們摸清楚了這個(gè)接口的一些參數(shù)幅恋,是不是可以把它封裝成一個(gè)python的function呢杏死?說(shuō)干就干,以下是完整的代碼:
import pandas as pd
import requests
import execjs

def get_eastMoney(start_date='2020-07-15', end_date='2020-07-15', page_index=1, page_number=50, fund_type='all', sc='6yzf'):
    """

    :param start_date:
    :param end_date:
    :param page_index:
    :param page_number:
    :param fund_type: 基金類型捆交,hh為混合淑翼,all為全部
    :param sc: 排序規(guī)則,6yzf為近六個(gè)月品追,1nzf為近1年
    :return:
    """
    url = 'http://fund.eastmoney.com/data/rankhandler.aspx?op=ph&dt=kf&rs=&gs=0&st=desc&qdii=&tabSubtype=,,,,,&dx=1&v=0.5137439179039982'
    cols=['代碼', '名稱', '簡(jiǎn)稱', '日期','單位凈值','累計(jì)凈值','日增長(zhǎng)率','近1周','近1月','近3月','近6月','近1年','近2年','近3年','今年來(lái)','成立來(lái)', '成立日期','自定義', 'A', 'B', '手續(xù)費(fèi)', 'C', 'D', 'E', 'F']
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
        'Host': 'fund.eastmoney.com',
        'Accept-Encoding': 'gzip, deflate',
        'Referer': 'http://fund.eastmoney.com/data/fundranking.html'
    }
    
    params = {
        'ft': fund_type,
        'sd': start_date,
        'ed': end_date,
        'pi': page_index,
        'pn': page_number,
        'sc': sc
    }
    
    response = requests.get(url, headers=headers, params=params)
    
    js_data = response.text[14:-1]
    dt = execjs.eval(js_data)
    print('allRecords: ', dt['allRecords'])
    em_data = pd.DataFrame(dt['datas'])[0].str.split(',', expand = True)
    em_data.columns = cols
    return em_data

df = get_eastMoney(fund_type='hh', page_number=500)

經(jīng)過(guò)一個(gè)簡(jiǎn)單的封裝玄括,我們就有了自己的python的函數(shù),以后我們只要通過(guò)一行代碼就可以得到想要的數(shù)據(jù)肉瓦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末遭京,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子泞莉,更是在濱河造成了極大的恐慌哪雕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲫趁,死亡現(xiàn)場(chǎng)離奇詭異斯嚎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門堡僻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)糠惫,“玉大人,你說(shuō)我怎么就攤上這事钉疫∨鸱恚” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵牲阁,是天一觀的道長(zhǎng)固阁。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咨油,這世上最難降的妖魔是什么您炉? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮役电,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘棉胀。我一直安慰自己法瑟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布唁奢。 她就那樣靜靜地躺著霎挟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪麻掸。 梳的紋絲不亂的頭發(fā)上酥夭,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音脊奋,去河邊找鬼熬北。 笑死,一個(gè)胖子當(dāng)著我的面吹牛诚隙,可吹牛的內(nèi)容都是我干的讶隐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼久又,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼巫延!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起地消,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤炉峰,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后脉执,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疼阔,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年适瓦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竿开。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谱仪。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖否彩,靈堂內(nèi)的尸體忽然破棺而出疯攒,到底是詐尸還是另有隱情,我是刑警寧澤列荔,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布敬尺,位于F島的核電站,受9級(jí)特大地震影響贴浙,放射性物質(zhì)發(fā)生泄漏砂吞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一崎溃、第九天 我趴在偏房一處隱蔽的房頂上張望蜻直。 院中可真熱鬧,春花似錦袁串、人聲如沸概而。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赎瑰。三九已至,卻和暖如春破镰,著一層夾襖步出監(jiān)牢的瞬間餐曼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工鲜漩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留源譬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓宇整,卻偏偏與公主長(zhǎng)得像瓶佳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鳞青,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容