python正则实战爬虫demo+数据清洗+存储到mysql数据库=你还在等什么?

项目目标

笔者,我们今天的目标是什么呢
在这里插入图片描述
:我思索了一下,我知道各位小白都是醉翁之意不在酒,在乎上水之间也,换而言之,都喜欢弄真demo,而不喜欢弄概念,上次出的python正则,让大家为难了,哈哈,所以我们今天的目标就是华夏基金网站,爬他。
网站地点请点击我

项目流程

那我们今天的项目流程是什么呢
问的好,只要思路清晰,还怕什么难题?

:如图所示的该网站一共有四张表,我们来使用python正则把这四张表里的数据爬下来,并进行数据清洗,存放到关系型数据库中。

在这里插入图片描述
任务分析
那我们该如何开始呢
:首先对源码全局进行分析,如下图所示,四个红色框框正是我们要获取的数据,我们首先需要先使用正则表达式,定一个搜索的范围,再进行获取想要的数据,这样能避免程序全局查找。这里为什么要定范围,我相信大家去写这个代码就能知道为什么了,这里就不阐述了。
在这里插入图片描述

任务步骤

步骤一:爬取四张数据表,并做适当的数据清洗

为什么要进行数据清洗?
:通过数据清洗,过滤掉无用的数据,存入数据库更为方便

将网页源码保存到文件中

import requests

def get_html():
    #进行get请求
    response=requests.get("http://fund.chinaamc.com/portal/cn/include/newproducthome.jsp")
    #获取网页源码
    response_html=response.content.decode('gbk')
    #打印网页源码
    print(response_html)
    return response_html

def save_html(response_html):
    #保存到本地
    with open('./fund.html','w',encoding='utf-8') as f:
        f.write(response_html)

def main():
    save_html(get_html())

if __name__ == '__main__':
    main()

运行结果
温馨小提示:打开文件如果如下图显示一万六千多行就代表网页源码存储成功
在这里插入图片描述

爬取第一张表

首先获取表名
先分析源码结构
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:可以看到上述三幅图箭头指向的就是我们需要获取的内容,并且画线的部分都是一样的结构,这样我们使用正则就很方便。所以我们分成三部分来获取:表头,基金名,内容。
获取表名,代码示例

#匹配第一张表的头部
import re


def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        #匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[0]


def get_one_list_header(response_html):
    # 写正则表达式
    pattern = re.compile('<span class="p16_libe">(.*?)</span>')
    # 进行文本的匹配
    result_one_header = pattern.findall(response_html)
    print(result_one_header[:-2])


def main():
    get_one_list_header(get_native_html())


if __name__ == '__main__':
    main()
 
'''
运行结果:
['基金简称', '基金代码', '净值日期', '净值', '累计净值', '涨跌幅', '成立日期', '申购状态', '赎回状态', '定投状态']

'''

爬取基金名字

#匹配第一张表的基金名字
import re

def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        #匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[0]

def get_html_one_fund(response_html):
    #进行正则表达式的书写
    pattern = re.compile('\.shtml\" title="(.*?)" target="_blank')
    #进行匹配文本
    result_one_name=pattern.findall(response_html)
    print(result_one_name)

def main():
    get_html_one_fund(get_native_html())

if __name__ == '__main__':
    main()

'''
运行结果:

['华夏翔阳两年定开混合', '华夏粤港澳大湾区创新100ETF', '华夏睿阳一年持有混合', '华夏全球股票(QDII)', '华夏领先股票', '华夏行业混合(LOF)', '华夏经典混合', '华夏兴华混合A', '华夏成长混合', '华夏回报混合A', '华夏兴和混合', '华夏大盘精选混合', '华夏红利混合', '华夏收入混合', '华夏稳增混合', '华夏回报二号混合', '华夏优势增长混合', '华夏蓝筹混合(LOF)', '华夏复兴混合', '华夏策略混合', '华夏盛世混合', '华夏永福混合A', '华夏永福混合C', '华夏医疗健康混合A', '华夏医疗健康混合C', '华夏安康债券A', '华夏安康债券C', '华夏希望债券A', '华夏希望债券C', '华夏债券A/B', '华夏债券C', '华夏稳定双利债券C', '华夏亚债中国指数A', '华夏亚债中国指数C', '华夏收益债券(QDII)A', '华夏收益债券(QDII)C', '华夏收益债券(QDII)A(美元)', '华夏纯债债券A', '华夏纯债债券C', '华夏双债债券A', '华夏双债债券C', '华夏聚利债券', '华夏中小板ETF', '华夏医药ETF', '华夏沪深300指数增强A', '华夏沪深300指数增强C', '华夏上证50ETF', '华夏沪深300ETF联接A', '华夏沪深300ETF联接C', '华夏恒生ETF', '华夏恒生ETF联接A', '华夏沪深300ETF', '华夏消费ETF', '华夏金融ETF', '华夏沪港通恒生ETF', '华夏沪港通恒生ETF联接A', '华夏沪港通恒生ETF联接C', '华夏MSCI中国A股国际通ETF', '华夏MSCI中国A股国际通ETF联接A', '华夏MSCI中国A股国际通ETF联接C', '华夏上证50ETF联接A', '华夏上证50ETF联接C', '华夏中证500ETF', '华夏中证500ETF联接A', '华夏国企改革混合', '华夏新趋势混合A', '华夏新趋势混合C', '华夏回报混合H', '华夏大中华混合(QDII)', '华夏消费升级混合A', '华夏消费升级混合C', '华夏新活力混合A', '华夏新活力混合C', '华夏经济转型股票', '华夏军工安全混合', '华夏恒利3个月定开债券', '华夏新机遇混合A', '华夏兴华混合H', '华夏高端制造混合', '华夏新起点混合A', '华夏大中华信用债券(QDII)A', '华夏大中华信用债券(QDII)C', '华夏大中华信用债券(QDII)A(美元)', '华夏乐享健康混合', '华夏新锦程混合A', '华夏智胜价值成长股票A', '华夏智胜价值成长股票C', '华夏新锦绣混合A', '华夏新锦绣混合C', '华夏创新前沿股票', '华夏可转债增强债券A', '华夏上证50AH优选指数(LOF)A', '华夏网购精选混合A', '华夏鼎融债券A', '华夏鼎融债券C', '华夏港股通精选股票(LOF)', '华夏鼎利债券A', '华夏鼎利债券C', '华夏移动互联混合(QDII)', '华夏移动互联混合(QDII)(美元)', '华夏磐泰混合(LOF)', '华夏圆和混合', '华夏鼎汇债券A', '华夏鼎汇债券C', '华夏鼎智债券A', '华夏鼎智债券C', '华夏行业景气混合', '华夏新锦顺混合A', '华夏新锦顺混合C', '华夏鼎隆债券A', '华夏鼎隆债券C', '华夏新锦汇混合A', '华夏睿磐泰盛定开混合', '华夏鼎茂债券A', '华夏鼎茂债券C', '华夏恒融定开债券', '华夏稳定双利债券A', '华夏新锦升混合A', '华夏磐晟混合(LOF)', '华夏能源革新股票', '华夏节能环保股票', '华夏研究精选股票', '华夏鼎诺三个月定期开放债券A', '华夏鼎祥三个月定期开放债券A', '华夏鼎瑞三个月定期开放债券A', '华夏聚惠FOF(A)', '华夏聚惠FOF(C)', '华夏短债债券A', '华夏短债债券C', '华夏睿磐泰茂混合A', '华夏睿磐泰茂混合C', '华夏创业板ETF', '华夏睿磐泰荣混合A', '华夏睿磐泰荣混合C', '华夏睿磐泰利混合A', '华夏睿磐泰利混合C', '华夏鼎兴债券A', '华夏鼎兴债券C', '华夏稳盛混合', '华夏鼎旺三个月定期开放债券A', '华夏永康添福混合', '华夏行业龙头混合', '华夏鼎泰六个月定期开放债券A', '华夏全球科技先锋混合(QDII)', '华夏3-5年中高级可质押信用债ETF联接A', '华夏3-5年中高级可质押信用债ETF联接C', '华夏3-5年中高级可质押信用债ETF', '华夏新时代混合(QDII)', '华夏3年封闭运作战略配售(LOF)', '华夏鼎沛债券A', '华夏鼎沛债券C', '华夏战略新兴成指ETF', '华夏鼎顺三个月定开债券A', '华夏优势精选股票', '华夏创业板ETF联接A', '华夏创业板ETF联接C', '华夏产业升级混合', '华夏中小板ETF联接A', '华夏中小板ETF联接C', '华夏养老2040三年持有混合(FOF)', '华夏恒生ETF联接C', '华夏中证500ETF联接C', '华夏上证50AH优选指数(LOF)C', '华夏鼎福三个月定开债券A', '华夏潜龙精选股票', '华夏鼎禄三个月定开债券A', '华夏中证央企ETF', '华夏聚丰混合(FOF)A', '华夏聚丰混合(FOF)C', '华夏鼎通债券A', '华夏鼎通债券C', '华夏新兴消费混合A', '华夏新兴消费混合C', '华夏中证央企ETF联接A', '华夏中证央企ETF联接C', '华夏中短债债券A', '华夏中短债债券C', '华夏中证四川国改ETF联接A', '华夏中证四川国改ETF联接C', '华夏鼎略债券A', '华夏鼎略债券C', '华夏鼎康债券A', '华夏鼎康债券C', '华夏全球聚享(QDII)A', '华夏全球聚享(QDII)C', '华夏全球聚享(QDII)A(美元)', '华夏中证四川国改ETF', '华夏科技成长股票', '华夏养老2050五年持有混合(FOF)', '华夏养老2045三年持有混合(FOF)A', '华夏养老2045三年持有混合(FOF)C', '华夏养老2035三年持有混合(FOF)A', '华夏养老2035三年持有混合(FOF)C', '华夏中债1-3年政金债指数A', '华夏中债1-3年政金债指数C', '华夏科技创新混合A', '华夏战略新兴成指ETF联接A', '华夏战略新兴成指ETF联接C', '华夏野村日经225ETF', '华夏创蓝筹ETF', '华夏创成长ETF', '华夏创蓝筹ETF联接A', '华夏创蓝筹ETF联接C', '华夏创成长ETF联接A', '华夏创成长ETF联接C', '华夏中债3-5年政金债指数A', '华夏中债3-5年政金债指数C', '华夏中证AH经济蓝筹股票指数A', '华夏中证AH经济蓝筹股票指数C', '华夏鼎琪三个月定开债券', '华夏鼎淳债券A', '华夏鼎淳债券C', '华夏恒益18个月定开债券', '华夏网购精选混合C', '华夏中证全指证券公司ETF', '华夏中证5G通信主题ETF', '华夏常阳三年定开混合', '华夏饲料豆粕期货ETF', '华夏中证银行ETF', '华夏鼎泓债券A', '华夏鼎泓债券C', '华夏逸享健康混合', '华夏稳健养老一年持有混合(FOF)', '华夏中证5G通信主题ETF联接A', '华夏中证5G通信主题ETF联接C', '华夏中证全指房地产ETF', '华夏新机遇混合C', '华夏新起点混合C', '华夏中证全指房地产ETF联接A', '华夏中证全指房地产ETF联接C', '华夏中证人工智能主题ETF', '华夏恒泰64个月定开债券', '华夏中证银行ETF联接A', '华夏中证银行ETF联接C', '华夏饲料豆粕期货ETF联接A', '华夏价值精选混合', '华夏饲料豆粕期货ETF联接C', '华夏国证半导体芯片ETF', '华夏中证新能源汽车ETF', '华夏睿磐泰兴混合', '华夏恒生ETF联接A(美元)', '华夏现金增利货币A/E', '华夏现金增利货币B', '华夏财富宝货币A', '华夏财富宝货币B', '华夏薪金宝货币', '华夏货币A', '华夏货币B', '华夏保证金货币A', '华夏保证金货币B', '华夏收益宝货币A', '华夏收益宝货币B', '华夏天利货币A', '华夏天利货币B', '华夏现金宝货币A', '华夏现金宝货币B', '华夏快线货币ETF', '华夏沃利货币A', '华夏沃利货币B', '华夏惠利货币A', '华夏惠利货币B', '华夏理财30天A', '华夏理财30天B', '华夏兴业封闭', '华夏兴和封闭(已退市)', '华夏能源ETF', '华夏材料ETF', '华夏鼎新债券A', '华夏鼎新债券I', '华夏新锦安混合A', '华夏新锦福混合A', '华夏新锦泰混合A', '华夏新锦泰混合C', '华夏新起航混合A', '华夏新起航混合C', '华夏理财21天A', '华夏理财21天B', '华夏新锦鸿混合A', '华夏新锦鸿混合C', '华夏鼎诚债券A', '华夏鼎诚债券I', '华夏鼎益债券A', '华夏鼎益债券I', '华夏新锦图混合A', '华夏新锦图混合C', '华夏新锦祥混合A', '华夏新锦略混合A', '华夏新锦略混合C', '华夏鼎实债券A', '华夏鼎实债券C']

'''

爬取表的内容

#匹配第一张表的内容
import re

def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        # 匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[0]


def get_html_one_content(response_html):
    #进行正则表达式的书写,缩小范围
    pattern = re.compile('<tr align="center".*?>[\w\W]*?</tr>')
    #进行匹配文本
    result_one_content=pattern.findall(response_html)
    #打印数据的长度
    print(len(result_one_content))
    #删除第一条无用的数据
    del result_one_content[0]
    for count,i in enumerate(result_one_content):
        #再次进行正则表达式的书写,精准匹配标签文本
        pattern = re.compile('<td height="30">(.*?)</td>')
        #进行匹配
        result_one_contentx=pattern.findall(i)
        #打印数据
        print(result_one_contentx[1:-1])


def main():
    get_html_one_content(get_native_html())

if __name__ == '__main__':
    main()

运行结果
在这里插入图片描述

爬取第二张表

小提示:方法跟获取第一次表一样,就不一一分析。
获取表头

# 获取第二张表的表头
import re


def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        # 匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[1]


def get_two_list_header(response_html):
    # 写正则表达式
    pattern = re.compile('<span class="p16_libe".*?>(.*?)</span>')
    # 进行文本的匹配
    result_two_header = pattern.findall(response_html)
    print(result_two_header[:-2])


def main():
    get_two_list_header(get_native_html())


if __name__ == '__main__':
    main()

'''
运行结果:

['基金简称', '基金代码', '净值日期', '(百)万份收益', '七日年化收益率(%)', '最近30天的年化(%)', '今年以来年化(%)', '成立日期', '申购状态', '赎回状态', '定投状态']


'''

获取基金名字

#获取第二张表的基金名称
import re

def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        #匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[1]


def get_html_two_fund(response_html):
    #进行正则表达式的书写
    pattern = re.compile('\.shtml\" title="(.*?)" target="_blank')
    # 进行匹配文本
    result_two_name = pattern.findall(response_html)
    print(result_two_name)


def main():
    get_html_two_fund(get_native_html())


if __name__ == '__main__':
    main()

'''
运行代码:

['华夏现金增利货币A/E', '华夏现金增利货币B', '华夏财富宝货币A', '华夏财富宝货币B', '华夏薪金宝货币', '华夏货币A', '华夏货币B', '华夏保证金货币A', '华夏保证金货币B', '华夏收益宝货币A', '华夏收益宝货币B', '华夏天利货币A', '华夏天利货币B', '华夏现金宝货币A', '华夏现金宝货币B', '华夏快线货币ETF', '华夏沃利货币A', '华夏沃利货币B', '华夏惠利货币A', '华夏惠利货币B']

'''

获取第二张表的内容

# 匹配第二张表的内容
import re


def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        # 匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[1]


def get_html_two_content(response_html):
    # 进行正则表达式的书写,缩小范围
    pattern = re.compile('<tr align="center" id="tr\d+">[\w\W]*?</tr>')
    # 进行匹配文本
    result_two_content = pattern.findall(response_html)
    # 打印数据的长度
    print(len(result_two_content))
    # 删除第一条无用的数据
    for count, i in enumerate(result_two_content):
        # 再次进行正则表达式的书写,精准匹配标签文本
        pattern = re.compile('<td height="30">(.*?)</td>')
        # 进行匹配
        result_two_contentx = pattern.findall(i)
        # 打印数据
        print(result_two_contentx[2:-3])


def main():
    get_html_two_content(get_native_html())


if __name__ == '__main__':
    main()

运行结果
在这里插入图片描述

爬取第三张表

获取表头

# 获取第三张表的表头
import re


def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        # 匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[2]


def get_three_list_header(response_html):
    # 写正则表达式
    pattern = re.compile('<span class="p16_libe".*?>(.*?)</span>')
    # 进行文本的匹配
    result_three_header = pattern.findall(response_html)
    print(result_three_header)


def main():
    get_three_list_header(get_native_html())


if __name__ == '__main__':
    main()

'''
运行结果:

['基金简称', '基金代码', '净值日期', '万份收益(元)', '七日年化收益率(%)', '运作期年化收益率(%) ', '成立日期', '申购状态', '赎回状态', '定投状态', '网上交易', '添加自选']

'''

获取基金名

#获取第三张表的基金名称
import re

def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        #匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[2]


def get_html_three_fund(response_html):
    #进行正则表达式的书写
    pattern = re.compile('\.shtml\" title="(.*?)" target="_blank')
    # 进行匹配文本
    result_three_name = pattern.findall(response_html)
    print(result_three_name)


def main():
    get_html_three_fund(get_native_html())


if __name__ == '__main__':
    main()

'''
运行结果:

['华夏理财30天A', '华夏理财30天B']
'''

获取表的内容

# 匹配第三张表的内容
import re


def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        # 匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[2]


def get_html_three_content(response_html):
    # 进行正则表达式的书写,缩小范围
    pattern = re.compile('<tr align="center".*?id="tr\d+">[\w\W]*?</tr>')
    # 进行匹配文本
    result_three_content = pattern.findall(response_html)
    # 打印数据的长度
    print(len(result_three_content))
    # 删除第一条无用的数据
    del result_three_content[0]
    for count, i in enumerate(result_three_content):
        # 再次进行正则表达式的书写,精准匹配标签文本
        pattern = re.compile('<td height="30">([\S\s]*?)</td>')
        # 进行匹配
        result_three_contentx = pattern.findall(i)
        # 打印数据
        print(result_three_contentx[2:-3])


def main():
    get_html_three_content(get_native_html())


if __name__ == '__main__':
    main()

'''
运行结果:

3
[' 001057', '2020-02-21', '0.6929', '2.538', '--\n\n    \t', '2012-10-24', '开放', '开放', '暂停']
[' 001058', '2020-02-21', '0.7586', '2.778', '--\n\n    \t', '2012-10-24', '开放', '开放', '暂停']

'''

爬取第四张表

爬取表头

# 获取第四张表的表头
import re


def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        # 匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[3]


def get_four_list_header(response_html):
    # 写正则表达式
    pattern = re.compile('<span class="p16_libe".*?>(.*?)</span>')
    # 进行文本的匹配
    result_four_header = pattern.findall(response_html)
    print(result_four_header[:-2])


def main():
    get_four_list_header(get_native_html())


if __name__ == '__main__':
    main()

'''
运行结果:

['基金简称', '基金代码', '净值日期', '净值', '累计净值', '成立日期 ', '到期日期', '定投状态', '交易状态']
'''

爬取基金名称

#获取第四张表的基金名称
import re

def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        #匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[3]


def get_html_four_fund(response_html):
    #进行正则表达式的书写
    pattern = re.compile('\.shtml\" title="(.*?)" target="_blank')
    # 进行匹配文本
    result_four_name = pattern.findall(response_html)
    print(result_four_name)


def main():
    get_html_four_fund(get_native_html())


if __name__ == '__main__':
    main()

'''
运行结果:

['华夏兴业封闭', '华夏兴和封闭(已退市)', '华夏能源ETF', '华夏材料ETF', '华夏鼎新债券A', '华夏鼎新债券I', '华夏新锦安混合A', '华夏新锦福混合A', '华夏新锦泰混合A', '华夏新锦泰混合C', '华夏新起航混合A', '华夏新起航混合C', '华夏理财21天A', '华夏理财21天B', '华夏新锦鸿混合A', '华夏新锦鸿混合C', '华夏鼎诚债券A', '华夏鼎诚债券I', '华夏鼎益债券A', '华夏鼎益债券I', '华夏新锦图混合A', '华夏新锦图混合C', '华夏新锦祥混合A', '华夏新锦略混合A', '华夏新锦略混合C', '华夏鼎实债券A', '华夏鼎实债券C']

'''

爬取表中的内容

# 匹配第四张表的内容
import re


def get_native_html():
    # 获取本地源码
    with open("./fund.html", 'r', encoding='utf-8') as f:
        # 匹配四大表的所有内容,匹配的结果为4条
        return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())[3]


def get_html_four_content(response_html):
    # 进行正则表达式的书写,缩小范围
    pattern = re.compile('<tr align="center".*?id="tr\d+">[\w\W]*?</tr>')
    # 进行匹配文本
    result_four_content = pattern.findall(response_html)
    # 打印数据的长度
    print(len(result_four_content))
    # 删除第一条无用的数据
    del result_four_content[0]
    for count, i in enumerate(result_four_content):
        # 再次进行正则表达式的书写,精准匹配标签文本
        pattern = re.compile('<td height="30">([\S\s]*?)</td>')
        # 进行匹配
        result_four_contentx = pattern.findall(i)
        # 打印数据
        print(result_four_contentx[2:-3])


def main():
    get_html_four_content(get_native_html())


if __name__ == '__main__':
    main()

运行结果:
在这里插入图片描述

步骤二:通过继承优化代码+通过mysql存储=终极代码

为什么要存入数据库中
:将清洗过的数据存入数据库是一劳永逸的,在小型公司数据库里面的数据就是这样一步一步建起来的,想用时再去数据库取,非常的方便。
为什么要通过继承来优化代码
:因为我发现代码中有很多的地方是相同的,所以我们可以通过继承来减少代码的重用率!
代码示例

import re, os


class deal_with_data(object):

    def __init__(self):
        # 判断是否已经将获取的源码保存到本地,如果否将重新保存
        if not os.path.exists('./fund.html'):
            self.response_html = requests.get(
                "http://fund.chinaamc.com/portal/cn/include/newproducthome.jsp").content.decode('gbk')
            with open('./fund.html', 'w', encoding='utf-8') as f:
                f.write(self.response_html)

    # 提取数据所在的四大区域
    def get_native_html(self):
        # 获取本地源码
        with open("./fund.html", 'r', encoding='utf-8') as f:
            # 匹配四大表的所有内容,匹配的结果为4条
            return re.findall(r'<table.*?id="tb\d{0,1}">[\w\W]*?</table>', f.read())


# 定义所有表头的父类
class table_header(object):

    def get_list_header(self, response_html):
        # 写正则表达式
        self.pattern = re.compile('<span class="p16_libe".*?>(.*?)</span>')
        # 进行文本的匹配
        self.result_header = self.pattern.findall(response_html)
        return self.result_header


# 定义所有基金名的父类
class table_fund(object):

    def get_fund(self, response_html):
        # 进行正则表达式的书写
        self.pattern = re.compile('\.shtml\" title="(.*?)" target="_blank')
        # 进行匹配文本
        self.result_name = self.pattern.findall(response_html)
        return self.result_name


#定义表一类
class table_one(deal_with_data, table_header, table_fund):
	
    def __init__(self):
        deal_with_data.__init__(self)
        self.response_html = self.get_native_html()[0]
	
	#定义获取表头的方法
    def get_one_list_header(self):
        return self.get_list_header(self.response_html)[:-2]
        
	#定义获取基金名称的方法
    def get_html_one_fund(self):
        return self.get_fund(self.response_html)
	
	#定义获取表内容的方法
    def get_html_one_content(self):
        # 进行正则表达式的书写,缩小范围
        self.pattern = re.compile('<tr align="center".*?>[\w\W]*?</tr>')
        # 进行匹配文本
        self.result_one_content = self.pattern.findall(self.response_html)
        # 打印数据的长度
        # print(len(self.result_one_content))
        # 删除第一条无用的数据
        del self.result_one_content[0]
        for count, i in enumerate(self.result_one_content):
            # 再次进行正则表达式的书写,精准匹配标签文本
            self.pattern = re.compile('<td height="30">(.*?)</td>')
            # 进行匹配
            self.result_one_contentx = self.pattern.findall(i)
            # 打印数据
            yield self.result_one_contentx[1:-1]


#定义表二类
class table_two(deal_with_data, table_header, table_fund):

    def __init__(self):
        deal_with_data.__init__(self)
        self.response_html = self.get_native_html()[1]

    def get_two_list_header(self):
        return self.get_list_header(self.response_html)[:-2]

    def get_html_two_fund(self):
        return self.get_fund(self.response_html)

    def get_html_two_content(self):
        # 进行正则表达式的书写,缩小范围
        self.pattern = re.compile('<tr align="center" id="tr\d+">[\w\W]*?</tr>')
        # 进行匹配文本
        self.result_two_content = self.pattern.findall(self.response_html)
        # 打印数据的长度
        # print(len(self.result_two_content))
        for count, i in enumerate(self.result_two_content):
            # 再次进行正则表达式的书写,精准匹配标签文本
            self.pattern = re.compile('<td height="30">(.*?)</td>')
            # 进行匹配
            self.result_two_contentx = self.pattern.findall(i)
            # 打印数据
            yield self.result_two_contentx[2:-3]


#定义表三类
class table_three(deal_with_data, table_header, table_fund):

    def __init__(self):
        deal_with_data.__init__(self)
        self.response_html = self.get_native_html()[2]

    def get_three_list_header(self):
        return self.get_list_header(self.response_html)[:-2]

    def get_html_three_fund(self):
        return self.get_fund(self.response_html)

    def get_html_three_content(self):
        # 进行正则表达式的书写,缩小范围
        self.pattern = re.compile('<tr align="center".*?id="tr\d+">[\w\W]*?</tr>')
        # 进行匹配文本
        self.result_three_content = self.pattern.findall(self.response_html)
        # 打印数据的长度
        # print(len(self.result_three_content))
        # 删除第一条无用的数据
        del self.result_three_content[0]
        for count, i in enumerate(self.result_three_content):
            # 再次进行正则表达式的书写,精准匹配标签文本
            self.pattern = re.compile('<td height="30">([\S\s]*?)</td>')
            # 进行匹配
            self.result_three_contentx = self.pattern.findall(i)
            # 打印数据
            yield self.result_three_contentx[2:-3]

#定义表四类
class table_four(deal_with_data, table_header, table_fund):

    def __init__(self):
        deal_with_data.__init__(self)
        self.response_html = self.get_native_html()[3]

    def get_four_list_header(self):
        return self.get_list_header(self.response_html)[:-2]

    def get_html_four_fund(self):
        return self.get_fund(self.response_html)

    def get_html_four_content(self):
        # 进行正则表达式的书写,缩小范围
        self.pattern = re.compile('<tr align="center".*?id="tr\d+">[\w\W]*?</tr>')
        # 进行匹配文本
        self.result_four_content = self.pattern.findall(self.response_html)
        # 打印数据的长度
        # print(len(self.result_four_content))
        # 删除第一条无用的数据
        del self.result_four_content[0]
        for count, i in enumerate(self.result_four_content):
            # 再次进行正则表达式的书写,精准匹配标签文本
            self.pattern = re.compile('<td height="30">([\S\s]*?)</td>')
            # 进行匹配
            self.result_four_contentx = self.pattern.findall(i)
            # 打印数据
            yield self.result_four_contentx[2:-3]


import pymysql


#定义保存到数据库的类
class shave_mysql(object):
    def __init__(self):
        # 初始化ip地址
        self.host = 'localhost'
        # 初始化权限登陆
        self.root = 'root'
        # 初始化密码
        self.passwd = 'ghjkl;\''
        # 初始化端口号
        self.port = 3306

    # 初次连接数据库创建四个表
    def Connect_mysql(self):
        # 连接mysql数据库
        self.db = pymysql.connect(host=self.host, user=self.root, password=self.passwd, port=self.port)
        # 获取MySQL的操作游标
        self.cursor = self.db.cursor()
        # 创建数据库
        self.cursor.execute("create database fund_data default character set gbk")
        print("数据库创建成功")
        self.db.close()

    # 编辑第一个表
    def store_table_one(self):
        # 连接第一个表
        self.db = pymysql.connect(host=self.host, user=self.root, password=self.passwd, port=self.port, db="fund_data")
        # 获取mysql的操作游标
        self.curosr = self.db.cursor()
        # 实例化表一
        self.table1 = table_one()
        # 获取表一的头
        self.table1_header = self.table1.get_one_list_header()
        # 获取表一的基金名称
        self.table1_fund = self.table1.get_html_one_fund()
        # 获取表一的内容
        self.table1_conent = self.table1.get_html_one_content()
        # 创建spl语句,定义表

        self.table_one = ["fund_name", "fund_code", "net_worth_date", "net_worth", "add_up_net_worth",
                          "increase_number", "set_up_date", "subscription_state", "redeem_state", "pledge_state"]

        self.sql_one_header = "create table if not exists fund_table_one(fund_name varchar(255),fund_code varchar(255),net_worth_date varchar(255),net_worth varchar(255),add_up_net_worth varchar(255),increase_number varchar(255),set_up_date varchar(255),subscription_state varchar(255),redeem_state varchar(255),pledge_state varchar(255))"

        try:
            # 提交创建表的sql语句
            self.curosr.execute(self.sql_one_header)
            print("创建表已成功")
        except:
            print("表已经创建")

        # 定义索引
        self.one_index = 0
        try:
            for i in self.table1_conent:
                self.value = ",".join('"%s"' % j for j in i)
                # 插入数据
                self.sql_one_content = 'insert into fund_table_one(fund_name,fund_code,net_worth_date,net_worth,add_up_net_worth,increase_number,set_up_date,subscription_state,redeem_state,pledge_state) values("{}",{})'.format(
                    self.table1_fund[self.one_index],
                    self.value)
                self.one_index += 1
                # 提交跟新数据的sql语句
                self.curosr.execute(self.sql_one_content)
            print("存入数据成功")
            self.db.commit()
        except:
            # 执行失败进行回滚
            self.db.roolback()
            print("存入数据已经失败执行回滚")

        # 关闭数据库
        self.db.close()

    def store_table_two(self):
        # 连接第一个表
        self.db = pymysql.connect(host=self.host, user=self.root, password=self.passwd, port=self.port, db="fund_data")
        # 获取mysql的操作游标
        self.curosr = self.db.cursor()
        # 实例化表二
        self.table2 = table_two()
        # 获取表二的头
        self.table2_header = self.table2.get_two_list_header()
        # 获取表二的基金名称
        self.table2_fund = self.table2.get_html_two_fund()
        # 获取表二的内容
        self.table2_content = self.table2.get_html_two_content()

        self.table_two = ["fund_name", "fund_code", "net_worth_date", "million_earnings", "seven_earnings",
                          "thirty_annualized_returns", "the_year_annualized_returns", "set_up_date",
                          "subscription_state", "redeem_state", "pledge_state"]

        self.sql_two_header = "create table if not exists fund_table_two(fund_name varchar(255),fund_code varchar(255),net_worth_date varchar(255),million_earnings varchar(255),seven_earnings varchar(255),thirty_annualized_returns varchar(255),the_year_annualized_returns varchar(255),set_up_date varchar(255),subscription_state varchar(255),redeem_state varchar(255),pledge_state varchar(255))"

        try:
            # 提交创建表的sql语句
            self.curosr.execute(self.sql_two_header)
            print("创建表已成功")
        except:
            print("表已经创建")

        # 定义索引
        self.two_index = 0
        try:
            for i in self.table2_content:
                self.value = ",".join('"%s"' % j for j in i)
                # 插入数据
                self.sql_two_content = 'insert into fund_table_two(fund_name, fund_code, net_worth_date, million_earnings, seven_earnings,thirty_annualized_returns, the_year_annualized_returns,set_up_date,subscription_state,redeem_state,pledge_state) values("{}",{})'.format(
                    self.table2_fund[self.two_index],
                    self.value)
                self.two_index += 1
                # print(self.sql_two_content)
                # 提交跟新数据的sql语句
                self.curosr.execute(self.sql_two_content)

            print("存入数据成功")
            #进行提交,否则无法更新
            self.db.commit()
        except:
            # 执行失败进行回滚
            self.db.roolback()
            print("存入数据已经失败执行回滚")

        # 关闭数据库
        self.db.close()

    def store_table_three(self):
        # 连接第一个表
        self.db = pymysql.connect(host=self.host, user=self.root, password=self.passwd, port=self.port, db="fund_data")
        # 获取mysql的操作游标
        self.curosr = self.db.cursor()
        # 实例化表二
        self.table3 = table_three()
        # 获取表二的头
        self.table3_header = self.table3.get_three_list_header()
        # 获取表二的基金名称
        self.table3_fund = self.table3.get_html_three_fund()
        # 获取表二的内容
        self.table3_content = [i for i in self.table3.get_html_three_content()]
        # 创建spl语句,定义表
        self.table_three = ["fund_name", "fund_code", "net_worth_date", "million_earnings", "seven_earnings",
                            "running_during_earnings", "set_up_data", "subscription_state", "redeem_state",
                            "pledge_state"]

        self.sql_three_header = "create table if not exists fund_table_three(fund_name varchar(255),fund_code varchar(255),net_worth_date varchar(255),million_earnings varchar(255),seven_earnings varchar(255),running_during_earnings varchar(255),set_up_data varchar(255),subscription_state varchar(255),redeem_state varchar(255),pledge_state varchar(255))"

        try:
            # 提交创建表的sql语句
            self.curosr.execute(self.sql_three_header)
            print("创建表已成功")
        except:
            print("表已经创建")

        # 定义索引
        self.three_index = 0
        try:
            for i in self.table3_content:
                self.value = ",".join('"%s"' % j for j in i)
                # 插入数据
                self.sql_three_content = 'insert into fund_table_three(fund_name,fund_code,net_worth_date,million_earnings,seven_earnings,running_during_earnings,set_up_data,subscription_state,redeem_state,pledge_state) values("{}",{})'.format(
                    self.table3_fund[self.three_index],
                    self.value)
                self.three_index += 1
                # 提交跟新数据的sql语句
                self.curosr.execute(self.sql_three_content)
            print("存入数据成功")
            # 进行提交,否则无法更新
            self.db.commit()
        except:
            # 执行失败进行回滚
            self.db.roolback()
            print("存入数据已经失败执行回滚")

        # 关闭数据库
        self.db.close()

    def store_table_four(self):
        # 连接第一个表
        self.db = pymysql.connect(host=self.host, user=self.root, password=self.passwd, port=self.port, db="fund_data")
        # 获取mysql的操作游标
        self.curosr = self.db.cursor()

        # 实例化表二
        self.table4 = table_four()
        # 获取表二的头
        self.table4_header = self.table4.get_four_list_header()
        # 获取表二的基金名称
        self.table4_fund = self.table4.get_html_four_fund()
        # 获取表二的内容
        self.table4_content = [i for i in self.table4.get_html_four_content()]
        # 创建spl语句,定义表
        self.table_four = ["fund_name", "fund_code", "net_worth_date", "net_worth", "add_up_net_worth", "set_up_data",
                           "expire_date", "pledge_state", "deal_state"]

        self.sql_four_header = "create table if not exists fund_table_four(fund_name varchar(255),fund_code varchar(255),net_worth_date varchar(255),net_worth varchar(255),add_up_net_worth varchar(255),set_up_data varchar(255),expire_date varchar(255),pledge_state varchar(255),deal_state varchar(255))"

        try:
            # 提交创建表的sql语句
            self.curosr.execute(self.sql_four_header)
            print("创建表已成功")

        except:
            print("表已经创建")

        # 定义索引
        self.four_index = 0
        try:
            for i in self.table4_content:
                #拼接sql语句所需要的value
                self.value = ",".join('"%s"' % j for j in i)
                # 插入数据
                self.sql_four_content = 'insert into fund_table_four(fund_name,fund_code,net_worth_date,net_worth,add_up_net_worth,set_up_data,expire_date,pledge_state,deal_state) values("{}",{})'.format(
                    self.table4_fund[self.four_index],
                    self.value)
                self.four_index += 1
                # print(self.sql_four_content)
                # 提交跟新数据的sql语句
                self.curosr.execute(self.sql_four_content)
            print("存入数据成功")
            # 进行提交,否则无法更新
            self.db.commit()
        except:
            # 执行失败进行回滚
            self.db.roolback()
            print("存入数据已经失败执行回滚")

        # 关闭数据库
        self.db.close()


def main():
    # 测试数据是否清洗到自己想要的结构
    # table1=table_one()
    # print(table1.get_one_list_header())
    # print(table1.get_html_one_fund())
    # for i in table1.get_html_one_content():
    #     print(i)
    # table2=table_two()
    # print(table2.get_two_list_header())
    # print(table2.get_html_two_fund())
    # for i in table2.get_html_two_content():
    #     print(i)
    # table3=table_three()
    # print(table3.get_three_list_header())
    # print(table3.get_html_three_fund())
    # for i in table3.get_html_three_content():
    #     print(i)
    # table4=table_four()
    # print(table4.get_four_list_header())
    # print(table4.get_html_four_fund())
    # for i in table4.get_html_four_content():
    #     print(i)
    # 实例化数据保存到mysql的类
    shave_mysql_x = shave_mysql()
    # 创建数据库
    shave_mysql_x.Connect_mysql()
    # 创建第一个表
    shave_mysql_x.store_table_one()
    # 创建第二个表
    shave_mysql_x.store_table_two()
    # 创建第三个表
    shave_mysql_x.store_table_three()
    # 创建第四个表
    shave_mysql_x.store_table_four()


if __name__ == '__main__':
    main()

'''
运行结果:

数据库创建成功
创建表已成功
存入数据成功
创建表已成功
存入数据成功
创建表已成功
存入数据成功
创建表已成功
存入数据成功
'''

步骤三:本地数据库的查看效果

查看数据库跟四个表是否创建充成功在这里插入图片描述
查看表一的所有数据
在这里插入图片描述
查看表二的所有数据
在这里插入图片描述
查看表三的所有数据
在这里插入图片描述
查看表四的所有数据
在这里插入图片描述
over!感觉还不错
觉得作者用心了,请留下宝贵的赞
在这里插入图片描述
来一波,推送吧!
群号:781121386
群名:人生苦短,我学编程
欢迎大家加入我们,一起交流技术!!!

  • 12
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值