Python搜寻器可以说很有趣且易于使用。现在,我想使用Python来抓取网页股票数据并将其保存到本地csv数据文件中,并且我想将股票数据保存到MySQL数据库中。需求就在那里,其余的都已满足。
在开始之前,请确保已安装MySQL,并且需要启动本地MySQL数据库服务。说到安装MySQL数据库,两天前当我在计算机上安装MySQL 5. 7时,我无法一直安装它。它总是提示缺少Visual Studio 2013 Redistributable,但我感到非常困惑。它已经被安装。问题是。在版本上,只需更改版本。小问题和大苦难,我不知道是否有人像我一样难过。
关闭业务,启动本地数据库服务:
以管理员身份打开“命令提示符(管理员)”,然后输入“ net start mysql57”(我将数据库服务名称定义为mysql57,可以在安装MySQL时进行修改)以启动该服务。请注意以管理员身份打开小黑匣子。如果您不是管理员,我会提示您这里没有权限。你可以试试看。
启动服务后,我们可以选择打开“ MySQL 5. 7 Command Line Client”小黑框,您需要输入数据库的密码,该密码是在安装过程中定义的,数据库操作可以在这里执行。
让我们开始吃饭吧。
一、 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
真正起作用的代码块:
Url = 'http://quote.eastmoney.com/stocklist.html'#东方财富网股票数据连接地址 filepath = 'D:\\data\\'#定义数据文件保存路径 #实施抓取 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 = 'http://quotes.money.163.com/service/chddata.html?code=0'+code+\ '&end=20161231&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP' urllib.request.urlretrieve(url, filepath+code+'.csv')
以上代码实现了搜寻器网页抓取股票数据并将其保存到本地文件中。有关爬虫的信息很多,其中大多数是例行的,所以我就不多说了。同时,本文的实现中提到了许多Web资源,我要感谢所有原始创建者!
首先查看爬网的结果。 CodeList是捕获的所有股票个代码的集合。我们可以看到它总共包含1416个元素,即1416 股票个数据。因为股票太多配资平台,所以以6开头的数据看起来像是上海股市股票数据(原谅我不了解金融情况)。
捕获的股票数据将存储在csv文件中,一个股票数据将存储在一个文件中。理论上,将有1416个csv文件,与股票中的代码数相同。但是请原谅我的败类速度股票行情导入数据库,下载它也很麻烦。
打开本地数据文件以查看捕获的数据是什么样的:
实际上,它与手动下载没有什么不同。要说的不同是,它解放了劳动力并提高了生产力(听起来像政治吗?)。
二、将数据存储在MySQL数据库中
首先建立本地数据库连接:
#数据库名称和密码 name = 'xxxx' password = 'xxxx' #替换为自己的用户名和密码 #建立本地数据库连接(需要先开启数据库服务) db = pymysql.connect('localhost', name, password, charset='utf8') cursor = db.cursor()
其中,当安装MySQL时设置数据库名称(名称)和密码(密码)。
创建一个专门用于存储此股票数据的数据库:
#创建数据库stockDataBase,如果存在则跳过 sqlSentence1 = "create database if not exists stockDataBase" cursor.execute(sqlSentence1)#选择使用当前数据库 sqlSentence2 = "use stockDataBase;" cursor.execute(sqlSentence2)
在第一次运行中,通常将正常创建数据库,但是如果您再次运行它,因为该数据库已经存在,请跳过创建并继续执行。创建数据库后,选择使用刚创建的数据库并将数据表存储在数据库中。
查看下面的特定存储代码:
#获取本地文件列
fileList = os.listdir(filepath)
#依次对每个数据文件进行存储 for fileName in fileList: data = pd.read_csv(filepath+fileName, encoding="gbk") #创建数据表,如果数据表已经存在,会跳过继续执行下面的步骤print('创建数据表stock_%s'% fileName[0:6]) sqlSentence3 = "create table if not exists stock_%s" % fileName[0:6] + "(日期 date, 股票代码 VARCHAR(10), 名称 VARCHAR(10), 收盘价 float,\
最高价 float, 最低价 float, 开盘价 float, 前收盘 float, 涨跌额 float, 涨跌幅 float, 换手率 float,\
成交量 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: sqlSentence4 = "insert into stock_%s" % fileName[0:6] + "(日期, 股票代码, 名称, 收盘价, 最高价, 最低价, 开盘价,\
前收盘, 涨跌额, 涨跌幅, 换手率, 成交量, 成交金额, 总市值, 流通市值) \
values ('%s',%s','%s',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)" % record #获取的表中数据很乱,包含缺失值、Nnone、none等,插入数据库需要处理成空值 sqlSentence4 = sqlSentence4.replace('nan','null').replace('None','null').replace('none','null') cursor.execute(sqlSentence4) except:#如果以上插入过程出错,跳过这条数据记录,继续往下进行 break
代码并不复杂,只需注意几点。
1.逻辑级别:
包含两个循环。外循环是代码股票的循环,内循环是当前股票的每个记录的循环。坦率地说,它是根据股票逐一存储的,对于每个股票,它都是根据其每日记录逐一存储的。这很简单又暴力吗?是的!没有考虑采用更优化的方法。
2.用于读取本地数据文件的编码方法:
使用’gbk’编码,默认值应为’utf8’,但它似乎不支持中文。
3.创建数据表:
类似地,如果数据表已经存在(确定是否存在),则跳过创建过程并继续以下步骤(将继续存储)。一个问题是数据可能会重复存储,您可以选择跳过存储或仅存储最新数据。我在这里没有考虑太多的额外处理。其次,指定字段格式,以下字段为交易量,交易金额,总市值和流通市值。由于数据量大,我们选择使用bigint类型。
4.未指定数据表的主键:
我最初计划将日期用作主键。后来,我发现获得的数据包含重复的日期数据。这破坏了主键的唯一性并导致了错误。然后,我对数据文件的考虑不多。内容,这些数据将不再使用,因此不会直接设置主键,以免造成麻烦。
5.构造sql语句sqlSentence4:
在此过程的实现中,股票数据直接记录为元组,然后使用字符串格式(%运算符)。我没有考虑过由它引起的准确性问题,我也不知道它是否会产生影响。有些%s带有一个”,它表示sql语句中的字符串。有一个%s’,只有右侧有一个单引号,与代码股票匹配,只有一个单引号股票行情导入数据库,这是因为从数据文件读取的字符串已经包含左侧的单引号,并且左侧不需要再次添加。这是数据文件格式的问题,并且预先使用单引号表示文本格式。
6.异常值处理:
文本文件包含非标准化数据,例如null值,None,none等。所有这些数据均被null替换股票配资,null是数据库的null值。
完成MySQL数据库数据存储后,您需要关闭数据库连接:
#关闭游标,提交,关闭数据库连接 cursor.close() db.commit() db.close()
如果不关闭数据库连接,则无法在MySQL端执行数据库查询和其他操作,这等同于正在占用的数据库。
三、 MySQL数据库查询
#重新建立数据库连接 db = pymysql.connect('localhost', name, password, 'stockDataBase') cursor = db.cursor() #查询数据库并打印内容 cursor.execute('select * from stock_600000') results = cursor.fetchall() for row in results: print(row) #关闭 cursor.close() db.commit() db.close()
一张一张地打印以上内容将使您一团糟。您也可以在MySQL端查看它。首先选择数据库:使用stockDatabase ;,然后查询:从stock_600000;中选择*,结果可能如下:
四、完整代码
实际上,整个过程完成了两个相对独立的过程:1.搜寻器获取网页股票数据并将其保存到本地文件; 2.将本地文件数据存储到MySQL数据库。没有直接考虑将从网页获取的数据实时(或通过临时文件)扔到数据库中,而跳过本地数据文件的过程。这只是实现此目的的一种尝试,代码没有进行任何优化考虑。它本身并没有实际使用,只是很有趣,几乎就像第一个一样。哈哈~~
#导入需要使用到的模块 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 #########################开始干活############################ Url = 'http://quote.eastmoney.com/stocklist.html'#东方财富网股票数据连接地址 filepath = 'C:\\Users\\Lenovo\\Desktop\\data\\'#定义数据文件保存路径 #实施抓取 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 = 'http://quotes.money.163.com/service/chddata.html?code=0'+code+\ '&end=20161231&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP' urllib.request.urlretrieve(url, filepath+code+'.csv') ##########################将股票数据存入数据库########################### #数据库名称和密码 name = 'xxxx' password = 'xxxx' #替换为自己的账户名和密码 #建立本地数据库连接(需要先开启数据库服务) db = pymysql.connect('localhost', name, password, charset='utf8') cursor = db.cursor() #创建数据库stockDataBase sqlSentence1 = "create database stockDataBase" cursor.execute(sqlSentence1)#选择使用当前数据库 sqlSentence2 = "use stockDataBase;" cursor.execute(sqlSentence2) #获取本地文件列表 fileList = os.listdir(filepath) #依次对每个数据文件进行存储 for fileName in fileList: data = pd.read_csv(filepath+fileName, encoding="gbk") #创建数据表,如果数据表已经存在,会跳过继续执行下面的步骤print('创建数据表stock_%s'% fileName[0:6]) sqlSentence3 = "create table stock_%s" % fileName[0:6] + "(日期 date, 股票代码 VARCHAR(10), 名称 VARCHAR(10),\ 收盘价 float, 最高价 float, 最低价 float, 开盘价 float, 前收盘 float, 涨跌额 float, \ 涨跌幅 float, 换手率 float, 成交量 bigint, 成交金额 bigint, 总市值 bigint, 流通市值 bigint)" cursor.execute(sqlSentence3) except: print('数据表已存在!') #迭代读取表中每行数据,依次存储(整表存储还没尝试过) print('正在存储stock_%s'% fileName[0:6]) length = len(data) for i in range(0, length): record = tuple(data.loc[i]) #插入数据语句 try: sqlSentence4 = "insert into stock_%s" % fileName[0:6] + "(日期, 股票代码, 名称, 收盘价, 最高价, 最低价, 开盘价, 前收盘, 涨跌额, 涨跌幅, 换手率, \ 成交量, 成交金额, 总市值, 流通市值) values ('%s',%s','%s',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)" % record #获取的表中数据很乱,包含缺失值、Nnone、none等,插入数据库需要处理成空值 sqlSentence4 = sqlSentence4.replace('nan','null').replace('None','null').replace('none','null') cursor.execute(sqlSentence4) except: #如果以上插入过程出错,跳过这条数据记录,继续往下进行 break #关闭游标,提交,关闭数据库连接 cursor.close() db.commit() db.close() ###########################查询刚才操作的成果################################## #重新建立数据库连接 db = pymysql.connect('localhost', name, password, 'stockDataBase') cursor = db.cursor() #查询数据库并打印内容 cursor.execute('select * from stock_600000') results = cursor.fetchall() for row in results: print(row) #关闭 cursor.close() db.commit() db.close()