看了一个基金的爬虫
并且还分析了年化收益率的top20
今天就来记录一下顺便也算是笔记了
首先上网页截图
然后分析一下我们的需求
黄色箭头所示
首先选择自定义排行
然后第一行的最右边勾选可购
然后我们去找数据接口
我试了一下不是静态的
然后打开f12
看到了接口
点开第一个链接
可以发现接口地址
返回值是一个类json的东西
可以看到是这样的
然后去解析一下
可以发现不是纯json
我们去手动的改一下格式
也就是去掉头部的那些没用的括号
然后和尾部一些没用的信息
再次解析一下
成功解析
再去看url中的参数
我们这次得到了50条数据
那么我们大概率猜测应该和这个参数有关
那就改一下试试咯
改成2,果然获取到了2条数据
且经过测试服务器对这个参数的最大值没有做限制
那也就是说我们可以直接把所有都一次性请求下来
ps:以后python写django分页的时候记得判断数量,不然这就给爬虫留下的余地
到这一步,我们的基本思路大概就是有了
1.请求接口
2.获取类json数据
3.解析成为json数据
4.处理json数据,取出咱们想要的top20
但是这里在第一步的时遇到一个小坑就是需要子啊headers中加上
代码语言:javascript复制'Referer':'http://某网站/data/diyfundranking.html'
不然会请求失败
那么也不废话了直接上代码
代码语言:javascript复制# 爬虫某基金网站,获得全部数据并计算平均年利率,并输入top20
import requests
import json
import datetime
import prettytable
class FundData:
fundCode="" #代码
fundName="" #名称
createDate="" #成立日期
totalGrowthRate="" #总的盈利率
totalDays=0 #运营的天数
avgYearGrowthRate=0 #平均年化收益率
#获得url返回值
def getTextFromUrl(url):
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'Referer':'http://某网站/data/diyfundranking.html'
}
res=requests.get(url,headers=headers)
result=res.text
return result
#解析url,返回json数据
def rseResText2JsonText(text):
#1.在字符串中找到要去掉的头部内容“datas”
startindex=text.find("datas:")
#2.找到最后一个 】 的位置
endIndex=text.find("],") 1
#3.通过起始位置和结束位置,截取到[]之间的内容
str=text[startindex:endIndex].replace("datas:","")
#4.然后将数据解析成json 返回
jsonList=json.loads(str)
return jsonList
#解析json数据,将基金数据转化为基金对象,计算平均年化收益
def parseJsonText2FundData(jsonText):
fundData=FundData()
arrField=jsonText.split(",")
fundData.fundCode=arrField[0]
fundData.fundName=arrField[1]
fundData.totalGrowthRate=float(arrField[3])
fundData.createDate=arrField[12]
#计算总的运营天数
createDate=datetime.datetime.strptime(fundData.createDate,"%Y-%m-%d")
fundData.totalDays=(datetime.datetime.now()-createDate).days
#计算平均年化收益率
fundData.avgYearGrowthRate=round(fundData.totalGrowthRate/(fundData.totalDays/365),2)
return fundData
下面是主函数
代码语言:javascript复制if __name__ == "__main__":
url="http://某网站/data/rankhandler.aspx?op=dy&dt=kf&ft=all&rs=&gs=0&sc=qjzf&st=desc&sd=2019-12-30&ed=2020-12-30&es=0&qdii=&pi=1&pn=500&dx=1&v=0.12869156386521285"
#1.调用接口,获得基金数据
resText=getTextFromUrl(url)
#2.解析数据,计算平均年化shouyilv
print(resText)
#3.按平均年化收益率排序
jsonl=rseResText2JsonText(resText)
fundDataList=[]
for jsonitem in jsonl:
fundDataList.append(parseJsonText2FundData(jsonitem))
fundDataList.sort(key=lambda x: x.avgYearGrowthRate,reverse=True)
#4.取出top20
top20List=fundDataList[0:20]
remark=1
pt=prettytable.PrettyTable()
pt.field_names=["排名","基金代码","基金名称","运营天数","平均年化收益率"]
for i in top20List:
#print("排名:",remark,"基金数据:",i.__dict__)
pt.add_row([
remark,
i.fundCode,
i.fundName,
i.totalDays,
i.avgYearGrowthRate
])
remark =1
print(pt)