【python爬虫】用python爬取股票数据

这几天把学习通的 python 爬虫相关课程给刷完了,想去动手也实践一下,重温一下很久之前学过的东西

然后发现实例2(爬淘宝那个)、实例3(爬股票那个),好像都有点问题。实例2是淘宝现在的反爬机制好像做的挺好,需要登录后才可以(当然也可能是我菜);实例3是百度的股票接口挂掉了。。
在这里插入图片描述
啊。。这。。
所以这篇文章以笔记的形式,记录一下另一种爬取股票数据的操作

需求分析

  • 目标:获取上交所和深交所所有股票的名称和交易信息
  • 输出:保存到文件中
  • 技术路线:requests & re & pandas & json

候选数据网站的选择

  • 选取原则:股票信息静态存在于 HTML 页面中,非 js 代码生成,没有 Robots 协议限制
  • 获取股票列表:
    • 东方财富网:http://79.push2.eastmoney.com/api/qt/clist/get(链接可能有所变化,不能直接打开,需要传递参数,请看下问分解

基本思路

  1. 打开 东方财富网行情中心
    在这里插入图片描述
    可以看到红色框框内有一堆股票数据,我们只需要找到这堆数据的返回接口即可(因为这个表格数据都是动态呈现的,如果使用 beautifulsoup4 直接做汤,表格内的数据都是 -),所以我们得去找数据接口
  2. F12 打开浏览器开发工具,找到 network 或者 网络
    在这里插入图片描述
    点击红色框框将当前网络请求记录清除,以便我们获取新的网络请求记录
  3. 点击网站表格下面的翻译,我们就会发现一条查询参数这么多的查询记录
    在这里插入图片描述
    点击预览我们就能看到与展示股票信息表格的对应信息的数据
    在这里插入图片描述
  4. 多翻几页表格,查看请求的参数变化,就能分析出请求参数有用的地方
    在这里插入图片描述
  5. 至此我们就可以根据标头查看我们所需的接口连接啦,每次打开这个连接可能前面的数字有所不同,但是都可有获取数据
    在这里插入图片描述
  6. 将全部请求的参数以字典的形式保存,然后在 requests.get() 的时候传递过去即可获得数据
  7. 使用 pandas 可以很方便的以 .csv 的格式导出数据文件到本地

当然,你不想看上面的内容,或者觉得我说的不是很清楚,也可以直接看下面的实现代码

实现代码

首先引入相关的第三方库与定义全局变量

import requests
import re
import json
import pandas

STOCK_LIST_URL = 'http://79.push2.eastmoney.com/api/qt/clist/get'

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
                  'like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edg/81.0.416.77',
    'Cookie': '你自己的 Cookie 信息'
}

#	这个查询参数可以直接复制,
PARAMS = {
    'cb': 'jQuery112406209406051182_1590109022697',
    'pn': 1,  # 页码
    'pz': 200,  # 每页的大小
    'po': 1,
    'np': 1,
    'ut': 'bd1d9ddb04089700cf9c27f6f7426281',
    'fltt': 2,
    'invt': 2,
    'fid': 'f3',
    'fs': 'm:0 t:6,m:0 t:13,m:0 t:80,m:1 t:2,m:1 t:23',
    'fields': 'f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152',
    '_': '1590109022826'
}

然后定义一个获得 HTMLtext 的函数 getHTMLText()

def getHTMLText(url, params):
    try:
        response = requests.get(url, headers=HEADERS, params=params)
        response.raise_for_status()
        response.encoding = response.apparent_encoding
        return response.text
    except:
        return ''

接着定义一个函数 getStockList() 处理我们获得的返回字符串信息

def getStockList(stockurl):
    html = getHTMLText(stockurl, PARAMS)
    if html == '':
        return print('获取 html 失败')
    #	找到相关数据并转换为字典的形式以方便得到数据列表
    stock_info_json = re.search(r'"diff":\[.*]', html).group(0)
    stock_info_dict = json.loads('{' + stock_info_json + '}')
    stock_info_list = stock_info_dict['diff']
    return stock_info_list

最后定义一个函数 getStockInfo() 处理列表中没项数据并最终保存到本地文件

def getStockInfo(stockinfolist, filepath):
    output_info_list = []
    list_len = 0
    for stock_info in stockinfolist:
        output_info = {}
        output_info['代码'] = stock_info['f12']
        output_info['名称'] = stock_info['f14']
        output_info['最新价'] = stock_info['f2']
        output_info['跌涨幅'] = stock_info['f3']
        output_info['跌涨额'] = stock_info['f4']
        output_info['成交量(手)'] = stock_info['f5']
        output_info['成交额'] = stock_info['f6']
        output_info['最高'] = stock_info['f15']
        output_info['最低'] = stock_info['f16']
        output_info['今开'] = stock_info['f17']
        output_info['昨收'] = stock_info['f18']
        list_len = list_len + 1
        print('\r当前进度:{:.2f}%'.format(list_len * 100 / len(stockinfolist)), end='')
        output_info_list.append(output_info)
    #   使用 pandas 库快速导出到csv
    pandas.DataFrame(output_info_list).to_csv(filepath, index=None)

直接定义一个主函数 spider() 运行即可~

def spider():
    output_file = 'demo.csv'
    stock_info_list = getStockList(STOCK_LIST_URL)
    getStockInfo(stock_info_list, output_file)


if __name__ == '__main__':
    spider()

实现效果

在这里插入图片描述
实现效果可能还是有点瑕疵,比如说股票的代码没有用0补全等,但大概能看~

以上就是全部过程,可能其中代码还有些不是很人性化的地方,比如还不能自动翻页爬数据等,希望大家多多指教,下面贴出完整源代码

import requests
import re
import json
import pandas

STOCK_LIST_URL = 'http://79.push2.eastmoney.com/api/qt/clist/get'

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
                  'like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edg/81.0.416.77',
    'Cookie': '你自己的 Cookie 信息'
}

PARAMS = {
    'cb': 'jQuery112406209406051182_1590109022697',
    'pn': 1,  # 页码
    'pz': 200,  # 每页的大小
    'po': 1,
    'np': 1,
    'ut': 'bd1d9ddb04089700cf9c27f6f7426281',
    'fltt': 2,
    'invt': 2,
    'fid': 'f3',
    'fs': 'm:0 t:6,m:0 t:13,m:0 t:80,m:1 t:2,m:1 t:23',
    'fields': 'f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152',
    '_': '1590109022826'
}


def getHTMLText(url, params):
    try:
        response = requests.get(url, headers=HEADERS, params=params)
        response.raise_for_status()
        response.encoding = response.apparent_encoding
        return response.text
    except:
        return ''


def getStockList(stockurl):
    html = getHTMLText(stockurl, PARAMS)
    if html == '':
        return print('获取 html 失败')
    # stock_code_list = re.findall(r'"\d{6}"', html)
    stock_info_json = re.search(r'"diff":\[.*]', html).group(0)
    stock_info_dict = json.loads('{' + stock_info_json + '}')
    stock_info_list = stock_info_dict['diff']
    return stock_info_list


def getStockInfo(stockinfolist, filepath):
    output_info_list = []
    list_len = 0
    for stock_info in stockinfolist:
        output_info = {}
        output_info['代码'] = stock_info['f12']
        output_info['名称'] = stock_info['f14']
        output_info['最新价'] = stock_info['f2']
        output_info['跌涨幅'] = stock_info['f3']
        output_info['跌涨额'] = stock_info['f4']
        output_info['成交量(手)'] = stock_info['f5']
        output_info['成交额'] = stock_info['f6']
        output_info['最高'] = stock_info['f15']
        output_info['最低'] = stock_info['f16']
        output_info['今开'] = stock_info['f17']
        output_info['昨收'] = stock_info['f18']
        list_len = list_len + 1
        print('\r当前进度:{:.2f}%'.format(list_len * 100 / len(stockinfolist)), end='')
        output_info_list.append(output_info)
    #   使用 pandas 库快速导出到csv
    pandas.DataFrame(output_info_list).to_csv(filepath, index=None)


def spider():
    output_file = 'demo.csv'
    stock_info_list = getStockList(STOCK_LIST_URL)
    getStockInfo(stock_info_list, output_file)


if __name__ == '__main__':
    spider()

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读