从页面读取数据每次都需要定位HTML标签,那么有没有更简洁的办法呢?

当然有,那就是找到页面数据的来源,分析哪些数据是我们想要的,直接通过WebAPI来获得数据。

我使用的是360极速浏览器,按F12后,再点“NetWork”,就可以看到页面加载的相关数据来源。

通过不断的更改日期,对比发现,上面两张图中红框部分就是页面数据产生变化的来源。

逐个点击红框中的链接,观察右侧返回的数据,判断对应页面上的区域。

经过分析,需要的数据在对应以下地址:

大盘涨跌数据:https://flash-api.xuangubao.cn/api/market_indicator/line?fields=rise_count,fall_count

涨停和跌停数据:https://flash-api.xuangubao.cn/api/market_indicator/line?fields=limit_up_count,limit_down_count

炸板率数据:https://flash-api.xuangubao.cn/api/market_indicator/line?fields=limit_up_broken_count,limit_up_broken_ratio

涨停个股列表:https://flash-api.xuangubao.cn/api/pool/detail?pool_name=limit_up

 直接访问上面的地址,发现返回的数据是JSON格式,接下来就简单了,使用Python的JSON处理模块即可。

参考代码如下:

from selenium import webdriver
from _datetime import datetime
import common.xgb_data as xd
import common.sqlite_oper as so
import time,json

#################################################
dapan = []          # 大盘数据
lianbanlist = []    # 涨停数据列表

# ——————判断是否有当天数据——————
# 返回值为0表示没有date日期的数据
def isload(date):
    sql = "select * from dapan where downdate='"+str(date)+"'"
    result = so.select(sql)
    return len(result)

# ——————将数据保存到sqlite数据库——————
# 返回值为0表示没有date日期的数据
def save_to_sqlite():
    # 保存大盘数据
    sql = "insert into dapan values('{0}',{1},{2},{3},{4},'{5}',{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16});".format(
        dapan.downdate, dapan.up, dapan.down, dapan.limitUp, dapan.limitDown, dapan.bomb, dapan.ban1, dapan.ban2, dapan.ban3,
        dapan.ban4, dapan.ban5, dapan.ban6, dapan.ban7, dapan.ban8, dapan.ban9, dapan.ban10, dapan.ban10s)
    so.exec(sql)
    # 保存涨停股数据
    for zt in lianbanlist:
        sql = "insert into zhangting values('{0}','{1}','{2}','{3}','{4}',{5});".format(
            zt.downdate, zt.scode, zt.sname, zt.stype, zt.zttime, zt.slevel)
        so.exec(sql)
    print(dapan.downdate+"的数据保存完毕")

# ——————统计每种连板情况的个数——————
def calc_lianban_amount(i):
    if i == 1:
        dapan.ban1 = int(dapan.ban1) + 1
    elif i == 2:
        dapan.ban2 += 1
    elif i == 3:
        dapan.ban3 +=1
    elif i == 4:
        dapan.ban4 += 1
    elif i == 5:
        dapan.ban5 += 1
    elif i == 6:
        dapan.ban6 += 1
    elif i == 7:
        dapan.ban7 += 1
    elif i == 8:
        dapan.ban8 += 1
    elif i == 9:
        dapan.ban9 += 1
    elif i == 10:
        dapan.ban10 += 1
    else:
        dapan.ban10s += 1

# ————得到大盘数据————
# 获取当天数据不用加日期,历史数据必须加date=xxxx-xx-xx
def get_today_data(date=datetime.now().date()):
    try:
        if (isload(date)>0):
            print("已经下载过"+str(date)+"的数据")
            return

        # ——创建大盘数据对象——
        global dapan    # 说明该变量是全局变量
        dapan = xd.DaPan(str(date), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

        chrome_options = webdriver.chrome.options.Options()
        chrome_options.add_argument("--headless")
        browser = webdriver.Chrome(chrome_options=chrome_options)
        # browser = webdriver.Chrome()
        # ——大盘涨跌数量——
        url = "https://flash-api.xuangubao.cn/api/market_indicator/line?fields=rise_count,fall_count"
        if (date != datetime.now().date()):
            url += "&date=" + str(date)
        browser.get(url)
        page = str(browser.page_source)  # 得到大盘涨跌数据
        page = page[page.find("{"):-20]
        data = json.loads(page)["data"]
        if(len(data)<=0):
            print("没有"+str(date)+"的数据")
            return
        d = json.loads(page)["data"][-1]    # 得到最后一次数据(收盘数据)
        dapan.up = d["rise_count"]      # 下跌数量
        dapan.down = d["fall_count"]    # 上涨数量

        time.sleep(1)
        # ——大盘涨跌停数量——
        url = "https://flash-api.xuangubao.cn/api/market_indicator/line?fields=limit_up_count,limit_down_count"
        if (date != datetime.now().date()):
            url += "&date=" + str(date)
        browser.get(url)
        page = str(browser.page_source)  # 得到页面源码
        page = page[page.find("{"):-20]
        d = json.loads(page)["data"][-1]     # 得到最后一次数据(收盘数据)
        dapan.limitUp = d["limit_up_count"]
        dapan.limitDown = d["limit_down_count"]

        time.sleep(1)
        # ——炸板率——
        url = "https://flash-api.xuangubao.cn/api/market_indicator/line?fields=limit_up_broken_count,limit_up_broken_ratio"
        if (date != datetime.now().date()):
            url += "&date=" + str(date)
        browser.get(url)
        page = str(browser.page_source)  # 得到页面源码
        page = page[page.find("{"):-20]
        d = json.loads(page)["data"][-1]  # 得到最后一次数据(收盘数据)
        dapan.bomb = str(round(d["limit_up_broken_ratio"]*100))+"%"

        time.sleep(1)

        # ——涨停板个股——
        url = "https://flash-api.xuangubao.cn/api/pool/detail?pool_name=limit_up"
        if(date != datetime.now().date()):
            url += "&date=" + str(date)
        browser.get(url)
        page = str(browser.page_source)  # 得到页面源码
        page = page[page.find("{"):-20]
        ztlist = json.loads(page)["data"]
        for data in ztlist:
            if (data["stock_chi_name"].find("ST") < 0):
                slevel = data["limit_up_days"]
                # 创建涨停对象
                zt = xd.ZhangTing(data["stock_chi_name"], data["symbol"],
                                  (data["surge_reason"]["related_plates"][0]["plate_name"] if(data["surge_reason"]!=None) else "无"),
                                  str(datetime.fromtimestamp(data["last_limit_up"]).time()),
                                  slevel, str(date))
                lianbanlist.append(zt)
                calc_lianban_amount(slevel)   # 计算连板数量

        time.sleep(1)
        browser.quit()

        #保存数据
        save_to_sqlite()
        return True
    except Exception as e:
        print ("出错了,\t", str(e))
        return False
#################################################

if __name__ == "__main__":
    get_today_data()

最后读取到的数据如下图:

 

Python爬取选宝股数据到此结束。

GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e 4 个月前
8c391e04 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐