Advertisement

python爬虫实现股票数据存储_Python爬虫抓取东方财富网股票数据并实现MySQL数据库存储!...

阅读量:

可以说这个Python程序既有趣又实用。
打算用Python来获取网页上的股票数据并将其保存到本地的一个CSV数据文件里。
不仅希望将这些股票数据存储在本地的一个CSV文件中。
需求已经明确……下一步就是去实现它了。

在安装MySQL之前,请确保MySQL已经正确安装,并已启动本地数据库服务。关于安装MySQL数据库的过程,在开始之前,请您确认是否已经正确配置了开发环境?提到安装 MySQL数据库时,请您耐心等待操作完成?死活装不上总是提示缺少Visual Studio 2013 Redistributable组件呀!但是很疑惑呀!原来问题出在软件版本的不兼容性上呀!更换合适的软件版本后即可解决问题呀!有没有人跟我一样遇到了类似的问题呢?

言归正传,启动本地数据库服务:

以管理员权限启动“命令提示符(管理员)”程序后,在终端中运行“net start mysql57”(其中我将数据库服务名称设定为mysql57,在安装MySQL时可以选择更改该值)即可启动服务。请注意,在启动小黑框窗口时必须使用管理员权限。如果当前账户不是管理员,则会因缺乏相应的权限而无法执行操作,请确保测试过程中遵循这一前提条件。

服务启动后,可以选择点击打开MySQL 5.7命令行界面小黑框,在输入之前需要输入数据库密码(安装时设置过的),这里提供了数据库操作功能。

下面开始上正餐。

一、Python爬虫抓取网页数据并保存到本地数据文件中

首先导入需要的数据模块,定义函数:

#导入需要使用到的模块

import urllib

import re

import pandas as pd

import pymysql

import os

#爬虫抓取网页函数

def getHtml(url):

html = urllib.request.urlopen(url).read()

html = html.decode('gbk')

return html

#抓取网页股票代码函数

def getStackCode(html):

s = r'

'

pat = re.compile(s)

code = pat.findall(html)

return code

[

](http://quote.eastmoney.com/\S\S(.*?).html)

真正干活的代码块:

[

](http://quote.eastmoney.com/\S\S(.*?).html)

链接地址:Url = 'http://quote.eastmoney.com/stocklist.html#东方财富网的股票数据连接地址

指定数据文件存储位置为'D:\data#',其中'#'用于标记HTML中的相关链接。
用于指定数据存储位置的变量设定。
此脚标将指向相关的网页内容。

#实施抓取

code = getStackCode(getHtml(Url))

收集全部上海市场股票信息(开头为数字6)的集合

CodeList = []

for item in code:

if item[0]=='6':

CodeList.append(item)

#抓取数据并保存到本地csv文件

for code in CodeList:

print('正在获取股票%s数据'%code)

链接地址基于条件的URL生成机制:当指定参数为code=0时会激活该服务端点指向的资源位置

'&end=20161231&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP'

[urllib.request.urlretrieve(url, filepath{code}.csv)]指向 quote.eastmoney.com 的一个动态网页。

[

](http://quote.eastmoney.com/\S\S(.*?).html)

上述代码实现了利用网络爬虫技术从网页中提取股票数据并将其存储于本地文件中。对于网络爬虫的相关知识已有丰富的参考资料可供查阅,默认采用标准化的获取流程。在此基础上也借鉴了多个公开可用的框架与工具,并衷心致谢所有提供原始代码的开发者。

首先查看抓取结果。CodeList记录了所有被抓取的股票代码集合体,在本例中共包含1416个元素(即共有1416支股票数据)。由于股票数量较多,在此次操作中我们仅选取了以数字6开头的部分(这可能属于沪深30支中的特定筛选标准)。

[

](http://quote.eastmoney.com/\S\S(.*?).html)

[

](http://quote.eastmoney.com/\S\S(.*?).html)

程序将获取的股票数据分别保存为独立的CSV文件,并确保每个股票对应单独一个CSV文件。预计生成约1416个CSV文件数量与股票代码一一对应。无奈我的网络速度较慢,下载一个都费劲,也是挺让人头疼的事。

[

](http://quote.eastmoney.com/\S\S(.*?).html)

打开一个本地数据文件看一下抓取的数据长什么样子:

[

](http://quote.eastmoney.com/\S\S(.*?).html)

实际上和人工手动下载并没有什么显著差异(这听起来更像是一个政治问题吗?)。如果说存在区别的话,那就是释放了人类的劳动潜力,并有效提升了生产效率。

二、将数据存储到MySQL数据库

首先建立本地数据库连接:

#数据库名称和密码

name = 'xxxx'

password = 'xxxx' #替换为自己的用户名和密码

建立本地数据库连接(需要先开启数据库服务)

创建本地数据库链接(在开启本地 databases服务之前)

通过pymysql.connect()函数建立本地数据库链接,默认字符编码为UTF-8字符集

cursor = db.cursor()

在默认配置下, 数据库名和口令被用来设置 MySQL 的安装过程.

创建数据库,专门用来存储本次股票数据:

#创建数据库stockDataBase,如果存在则跳过

#建立数据库StockDatabase,并在已有实例时不做处理

sqlSentence1 = "create database if not exists stockDataBase"

This SQL statement is executed by the cursor to choose the current database.

sqlSentence2 = "use stockDataBase;"

cursor.execute(sqlSentence2)

通常在首次运行时会成功地建立数据库;然而,在再次运行时(因为数据库已存在),则会跳过创建步骤并继续执行后续操作。建立完成后,请选择并使用新建立的数据库,在其中存储数据表。

下面看具体的存储代码:

[

](http://quote.eastmoney.com/\S\S(.*?).html)

#获取本地文件列

fileList = os.listdir(filepath)

#依次对每个数据文件进行存储

for fileName in fileList:

data = pd.read_csv(filepath+fileName, encoding="gbk")

#创建数据表,如果数据表已经存在,会跳过继续执行下面的步骤print('创建数据表stock_%s'% fileName[0:6])

#建立数据表stock_%s(其中已存在的数据表将被跳过)并继续执行以下步骤print('创建数据表stock_%s'% fileName[0:6])

sqlSentence3 = "如果不存在就创建表" % fileName[0:6] + "(日期 date, 股票代码字段 VARCHAR(10), 名称字段 VARCHAR(10), 收盘价 float, URL http://quote.eastmoney.com/\S\S(.*?).html)"

[最高价 float, 最低价 float, 开盘价 float, 前收盘 float, 涨跌额 float, 涨跌幅 float, 换手率 float,](http://quote.eastmoney.com/\S\S(.*?).html)

成交量 bigint, 成交金额 bigint, 总市值 bigint, 流通市值 bigint)"

cursor.execute(sqlSentence3)用于实现逐行获取表格数据并按顺序保存至本地文件中(整体一次性存储尚未实施)

print('正在存储stock_%s'% fileName[0:6])

length = len(data)

for i in range(0, length):

record = tuple(data.loc[i])

#插入数据语句

try:

将该操作插入到股票_中,并包含字段:日期、股票代码和名称;收盘价、最高价、最低价和开盘价。

[前收盘价, 涨跌幅, 涨跌幅, 成交量占比率, 交易量, 成交额, 总市值, 流通市值) ](http://quote.eastmoney.com/\S\S(.*?).html)

values ('%s',%s','%s',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)" % record

#表中数据呈现混乱状态,在缺失值、Nnone及none等特殊情况下插入数据库需进行特殊处理以转换为null值形式

该代码段通过一系列操作将变量sqlSentence4中的特定字符(如'nan'、'None'、'none')逐一替换成'dataNullValue', 从而实现数据统一处理的目的

cursor.execute(sqlSentence4)

除非上述插入过程出现错误情况,默认跳过当前条目数据记录,并继续执行后续操作

break

[

](http://quote.eastmoney.com/\S\S(.*?).html)

代码相对而言较为简单,在编写过程中只需关注几个关键点即可完成任务

1.逻辑层次:

涉及两个嵌套循环结构,在外部处理每个股票代码,在内部处理每个交易日记录的具体数据。这种方式是否显得非常直接且粗略?确实如此!但并未考虑到更为优化的方法!

2.读取本地数据文件的编码方式:

采用GBK编码时,默认应是UTF8编码;然而目前该功能无法处理中文内容。

3.创建数据表:

同样地,在现有数据表存在的前提下(通过if not exists进行检测),无需创建新表(随后完成后续操作)。需要注意的是,在后续的数据存储过程中(涉及的字段包括成交量、成交金额、总市值及流通市值),可能会出现重复记录的情况。对此有两种解决方案:可以选择跳过记录或仅保留最新记录。目前并未考虑其他额外处理措施。

4.没有指定数据表的主键:

最初本打算将日期设为主键字段。然而,在实际操作后发现数据集中存在大量重复的日期记录这一现象严重破坏了主键字段的独特性并可能导致后续程序运行时出现逻辑错误。因此没有深入探究数据文件的具体内容而直接放弃了对主键字段进行设置以避免可能的技术问题。

5.构造sql语句sqlSentence4:

该过程实现中,直接把股票数据记录tuple了,然后使用字符串格式化(%操作符)。造成的精度问题没有多考虑,不知道会不会产生什么样的影响。%s有的上边带着' ',是为了在sql语句中表示字符串。其中有一个%s',只有右边有单引号,匹配的是股票代码,只有一边单引号,这是因为从数据文件中读取到的字符串已经包含了左边的单引号,左边不需要再添加了。这是数据文件格式的问题,为了表示文本形式预先使用了单引号。

6.异常值处理:

在文本文件中存在非标准数据项如空值(None)、non-null处理等情况时,现将所有这些非标准数据项统一替代为null,并对应于数据库中的空值定义。

完成后需去做关闭数据库连接

#关闭游标,提交,关闭数据库连接

cursor.close()

db.commit()

db.close()

未关闭数据库连接意味着无法在MySQL端执行相应的查询操作,并等同于资源已被占用

三、MySQL数据库查询

[

](http://quote.eastmoney.com/\S\S(.*?).html)

#重新建立数据库连接

db变量 = $pymysql.connect('localhost', name, password, '股票数据存储库')

cursor = db.cursor()

#查询数据库并打印内容

cursor.execute('select * from stock_600000')

results = cursor.fetchall()

for row in results:

print(row)

#关闭

cursor.close()

db.commit()

db.close()

[

](http://quote.eastmoney.com/\S\S(.*?).html)

以上内容会逐条展示混乱不堪的状态。另外,在MySQL平台中也可以实现数据浏览功能。具体操作步骤如下:
首先选择数据库并执行命令:use stockDatabase;
接着执行查询操作:select * from stock_600000;
通过MySQL端可以查看生成的具体结果。

四、完整代码

[

](http://quote.eastmoney.com/\S\S(.*?).html)

#导入需要使用到的模块

import urllib

import re

import pandas as pd

import pymysql

import os

#爬虫抓取网页函数

def getHtml(url):

html = urllib.request.urlopen(url).read()

html = html.decode('gbk')

return html

#抓取网页股票代码函数

def getStackCode(html):

s = r'

全部评论 (0)

还没有任何评论哟~