Python股票分时数据爬取Demo
引言
之前用过一些量化平台,但是其免费版都没有提供股票分时数据,所以一直就想着有空自己去抓一些分时数据线分析。今天研究了下,做了个小demo,把整个过程整理下分享给大家。
目标URL
我们第一任务是找到一个能提供数据的URL。但首先找一个能提供股票数据的网站。平时用的比较多的有东方财富、腾讯、网易等等。我这里就找了东方财富,网上说它没有反爬。
第1步 打开东方财富,找到一只股票的交易网页。点一点里面的分时图或什么的,尽量到找一个只包含我们想要的数据网页。杂乱的数据越少越适合我们分析。
我点了全屏,以为是个新网页,数据会少点。但不是,不过看得页面清爽点也行。
第2步 我们在分时图上找到某个时间点的股价,比如9:40,股价7.33。因为要去找到分时数据是通过哪个URL请求得来,所以尽量挑一个只会出现在分时明细数据中的数据。当前页面还包含委托和盘口,所以我们挑的那个数字越unique,那后面的分析越简单。
第3步 分析当前页面的所有URL请求,看看哪个返回了分时数据。如上图,进入浏览器的开发者模式,在【网络】中搜索前面记的数字【7.33】。这边返回了一堆,仔细看了下分时图,这支股票在7.33 反复震荡,所以返回结果很多。其实分析URL请求的方法,就是看返回结果是不是我们要的。
第4步 多分析几个URL请求,差不多就能找到个最像的了。
接下来就是参数分析,方法就是多看几只不同的股票,看看哪些参数不同。自己换一换参数,发送请求,看能不能得到想要的结果。我的分析结果见下图。其实在分析“ut” 这个参数的时候,我用上面搜索的方法找到了包含这个参数一些Javascript 代码,那里面有对一些字段注释,至少f1,f2..f58 是啥都有注释,大家也可以试一试。
至此目标URL找到了。
返回数据
接下来就是分析返回数据的格式,以便我们后面设计取数逻辑。
第5步 还是在开发者工具中分析:返回数据是一个类似“jsonp12345(…)”结构的文本字符串。括号中是真正的json 格式数据,而目标数据包含在其data.trends中,以数组形式存在。这个返回结果还是比较容易抓出来的。
构建程序
第6步 设计代码脚本。
构建一个函数用于生成URL
再构建一个函数用于解析返回值并返回分时数据
串起来测一下
总结
到这里我们构建了一个简单的股票分时数据爬虫程序,当然还不完善,可以进一步扩展改进。但更多的是想演示下在这过程中如何一步一步分析和思考,希望对大家未来的工作或者学习有一点参考作用。
另外,说下爬虫使用:爬虫是否合法一直有争议的,本只是单纯的技术,一般不违法。但如果它的使用可能对别人造成损失伤害,或者用于商业目的,那用之前,最好Think Twice。这也是我上面的demo 没有实现批量下载的原因,以免操作不当,对别人服务器带来影响。
以下是全部代码:
import pandas as pd
import requests
import json
import re
import time
import random
"""
生成获取分时股价数据所需的URL
参数:
book id: 股票代码
返回:
string 类型URL
"""
def gen_url(book_id):
mkt_id = "0" if book_id[0] == '0' else "1"
timestamp = time.time() * 1000
url = "https://push2his.eastmoney.com/api/qt/stock/trends2/get?"
params = {
"fields1": "f1,f5",
"fields2":"f51,f52,f53,f54,f55,f56,f57",
"ut" : "fa5fd1943c7b386f172d6893dbfba10b",
"secid" : mkt_id + "." + book_id,
"ndays" : "1",
"iscr" : "0",
"iscca" : "0",
"cb" :"jsonp" + str(round(timestamp + random.random() * 1000001))
}
url_param = "&".join(p + "=" + v for p, v in params.items())
url += url_param
return url
"""
从服务器返回文本中提取分时数据
参数:
res_raw_text: 服务器的返回记录, string 类型
返回:
dataframe 分时数据
Raises:
KeyError - 这里就略了 LOL
"""
def get_min_price(res_raw_text):
res_text = re.findall(r"\((.*)\)", res_raw_text)
rs = json.loads(res_text[0])
trend_list = rs['data']['trends']
df = pd.DataFrame(columns=['time','open','close','high','low','volume','amount']
, data = [sub.split(",") for sub in trend_list])
return df
"""Test"""
stock_id = '601328'
url = gen_url(stock_id)
res = requests.get(url)
df = get_min_price(res.text)
作者:八两咖啡