当前位置:   article > 正文

python:爬虫 :爬取股票信息应用实例并入库mysql,进而实现可视化_爬取网页,采集网站数据和日志数据储存进mysql,并实现数据预处理和数据可视化

爬取网页,采集网站数据和日志数据储存进mysql,并实现数据预处理和数据可视化
  1. 候选数据网站的选择
  2. 选取原则:股票信息静态存在于HTML页面中,非js代码生成,没有Robots协议限制
  3. 选取方法:浏览器F12,源代码查看等
  4. 程序的结构设计:
  5. 步骤1:从东方财富网获取股票列表
  6. 步骤2:根据股票列表 逐个到百度股票获取个股信息
  7. 步骤3:将结果存储到文件

参考视频:https://www.bilibili.com/video/av9784617?p=47

代码:

  1. import requests
  2. import time
  3. from bs4 import BeautifulSoup
  4. import traceback
  5. import re
  6. def getHTMLText(url,code='utf-8'):
  7. try:
  8. r = requests.get(url,timeout=30)
  9. r.raise_for_status()
  10. r.encoding= code # 页面自动解析编码写法 r.encoding= r.apparent_encoding
  11. return r.text
  12. except:
  13. return ""
  14. def getStockList(lst,stockURL):
  15. html = getHTMLText(stockURL)
  16. soup = BeautifulSoup(html,"html.parser")
  17. a = soup.find_all('a')
  18. for i in a :
  19. # print(type(i)) #<class 'bs4.element.Tag'>
  20. # s = "连板"
  21. # print(s)
  22. # if s in str(i): #判断字符串中是否包含子串
  23. try:
  24. href= i.attrs['href']
  25. lst.append(re.findall(r"\d{6}",href)[0]) #以s开头 然后是h或z字母(因为股票代码不是上海sh就是深圳sz开头) 注意:re.findall返回列表,如[sh100012] 然后再取值出sh100012 然后再append,否则就append进去[[sh100012]]了
  26. except:
  27. continue
  28. def getStockInfo(lst,stockURL,fpath):
  29. count=0 # 实现 进度条
  30. for stock in lst:
  31. url = stockURL + stock +".html" #拼接url
  32. html = getHTMLText(url) # 获取股票页面内容
  33. try:
  34. if html == "": #空页面的处理
  35. continue
  36. infoDict = {}
  37. soup = BeautifulSoup(html,'html.parser') # 解析网页
  38. text =soup.text
  39. # 正则匹配出股票名称
  40. stockName = re.search(r'[\w\u4e00-\u9fcc]+',text).group(0)
  41. # 正则匹配出股票代码
  42. stockNumber = re.search(r'[0-9]\d{5}',text).group(0)
  43. # 正则匹配出股票个股日历
  44. p = re.compile(r"[个][股][日][\u4e00-\u9fa5]+[\s\S]+")
  45. stockHistory=p.findall(text)
  46. print(stockHistory)
  47. stockHistory1= re.split(r" +",stockHistory[0]) #按照多个空格分割
  48. print(stockHistory1[0])
  49. #将“个股日历 替换为空格”
  50. stockHistory2 = stockHistory1[0].replace("个股日历","")
  51. print(stockHistory2)
  52. stockHistory3 = stockHistory2.replace("\n",";",100).replace("\r",";")
  53. print(str(stockHistory3))
  54. infoDict.update({'股票名称':stockName}) #将 这个信息增加到字典中
  55. infoDict.update({'股票代码':stockNumber}) #将 这个信息增加到字典中
  56. infoDict.update({'股票日历':stockHistory2}) #将 这个信息增加到字典中
  57. # 股票信息部分如下
  58. # keyList = stockInfo.find_all('dt') #键
  59. # valueList = stockInfo.find_all('dd') #值
  60. # 还原为键值对并存到字典中
  61. # for i in range(len(keyList)):
  62. # key = keyList[i].text
  63. # val = valueList[i].text
  64. # infoDict[key]= val #字典可以直接使用key=value向字典中新增内容
  65. #将相关股票信息保存在文件中
  66. with open(fpath,'a',encoding='utf-8') as f:
  67. f.write(str(infoDict) + '\n')
  68. count = count +1 # 实现 进度条
  69. print('\r当前速度:{:.2f}%'.format(count * 100/len(lst)),end='') # \r能够将我们打印的字符串的最后的光标提到当前这一行的头部,那么下一次再进行 相关打印的时候,打印信息就会覆盖之前的内容。实现一个不换行的动态展示的进度条
  70. # 每10秒抓一次数据
  71. time.sleep(10)
  72. except:
  73. count = count +1 # 实现 进度条
  74. print('\r当前速度:{:.2f}%'.format(count * 100/len(lst)),end='')
  75. traceback.print_exc()
  76. continue
  77. if __name__ == '__main__':
  78. # stock_list_url = "https://www.banban.cn/gupiao/list_sh.html"
  79. stock_list_url = "https://www.banban.cn/gupiao/list_sz.html"
  80. # stock_info_url = "http://quote.eastmoney.com/sh" #sh上证 sz深圳
  81. stock_info_url = "http://quote.eastmoney.com/sz"
  82. output_file = "D://pythontest/files/gupiao/gupiao20191212.txt"
  83. # slist = ['002656','002702','000001','000002']
  84. slist=[]
  85. getStockList(slist,stock_list_url)
  86. getStockInfo(slist,stock_info_url,output_file)

抓取多个信息并入库mysql实例:

  1. import requests
  2. from bs4 import BeautifulSoup
  3. import traceback
  4. import re
  5. from 基础用法.toMysql import ToMySql
  6. def getHTMLText(url,code='utf-8'):
  7. try:
  8. r = requests.get(url,timeout=30)
  9. r.raise_for_status()
  10. r.encoding= code # 页面自动解析编码写法 r.encoding= r.apparent_encoding
  11. return r.text
  12. except:
  13. return ""
  14. def getStockList(lst,stockURL):
  15. html = getHTMLText(stockURL)
  16. soup = BeautifulSoup(html,"html.parser")
  17. a = soup.find_all('a')
  18. for i in a :
  19. try:
  20. href= i.attrs['href']
  21. lst.append(re.findall(r"\d{6}",href)[0]) #以s开头 然后是h或z字母(因为股票代码不是上海sh就是深圳sz开头) 注意:re.findall返回列表,如[sh100012] 然后再取值出sh100012 然后再append,否则就append进去[[sh100012]]了
  22. except:
  23. continue
  24. def getStockInfo(lst,stockURL,fpath):
  25. count=0 # 实现 进度条
  26. for stock in lst:
  27. url = stockURL + stock +".html" #拼接url
  28. html = getHTMLText(url) # 获取股票页面内容
  29. print('==================')
  30. print(url)
  31. try:
  32. if html == "": #空页面的处理
  33. continue
  34. infoDict = {}
  35. soup = BeautifulSoup(html,'html.parser') # 解析网页
  36. text =soup.text
  37. # 正则匹配出股票名称
  38. stockName = re.search(r'[\w\u4e00-\u9fcc]+',text).group(0)
  39. # 正则匹配出股票代码
  40. stockNumber = re.search(r'[0-9]\d{5}',text).group(0)
  41. # 正则匹配出股票个股日历
  42. jk = re.compile(r"[今][开][::][0-9]*[.][0-9]*")
  43. zs = re.compile(r"[昨][收][::][0-9]*[.][0-9]*")
  44. zg = re.compile(r"[最][高][::][0-9]*[.][0-9]*")
  45. zd = re.compile(r"[最][低][::][0-9]*[.][0-9]*")
  46. hsl = re.compile(r"[换][手][率][::][0-9]*[.][0-9]*")
  47. syl = re.compile(r"[市][盈][率][::][0-9]*[.][0-9]*")
  48. jkV=jk.findall(text)
  49. zsV=zs.findall(text)
  50. zgV=zg.findall(text)
  51. zdV=zd.findall(text)
  52. hslV=hsl.findall(text)
  53. sylV=syl.findall(text)
  54. # print(sylV[0])
  55. hslV = str(hslV[0])+"%"
  56. print(jkV[0])
  57. print(jkV[0].split(":")[1])
  58. print(zsV[0])
  59. print(zgV[0])
  60. print(zdV[0])
  61. print(str(hslV))
  62. print(sylV[0])
  63. # 将数据写入mysql
  64. sql = """ INSERT INTO stock_infos(stock_name,stock_code,jk,zs,zg,zd,hsl,syl) VALUES(%s,%s,%s,%s,%s,%s,%s,%s) """
  65. data = (stockName,stockNumber,jkV[0].split(":")[1],zsV[0].split(":")[1],zgV[0].split(":")[1],zdV[0].split(":")[1],hslV.split(":")[1],str(sylV[0].split(":")[1])) #直接写数字类型也能写入
  66. result = ToMySql.writeDb(sql, data)
  67. # 将数据写入文件中
  68. infoDict.update({'名称':stockName}) #将 这个信息增加到字典中
  69. infoDict.update({'代码':stockNumber})
  70. infoDict.update({'今开':jkV[0].split(":")[1]})
  71. infoDict.update({'昨收':zsV[0].split(":")[1]})
  72. infoDict.update({'最高':zgV[0].split(":")[1]})
  73. infoDict.update({'最低':zdV[0].split(":")[1]})
  74. infoDict.update({'换手率':hslV.split(":")[1]})
  75. infoDict.update({'市盈率':str(sylV[0].split(":")[1])})
  76. #将相关股票信息保存在文件中
  77. with open(fpath,'a',encoding='utf-8') as f:
  78. f.write(str(infoDict) + '\n')
  79. count = count +1 # 实现 进度条
  80. print('\r当前速度:{:.2f}%'.format(count * 100/len(lst)),end='') # \r能够将我们打印的字符串的最后的光标提到当前这一行的头部,那么下一次再进行 相关打印的时候,打印信息就会覆盖之前的内容。实现一个不换行的动态展示的进度条
  81. # 每10秒抓一次数据
  82. # time.sleep(10)
  83. except:
  84. count = count +1 # 实现 进度条
  85. print('\r当前速度:{:.2f}%'.format(count * 100/len(lst)),end='')
  86. traceback.print_exc()
  87. continue
  88. if __name__ == '__main__':
  89. # stock_list_url = "https://www.banban.cn/gupiao/list_sh.html"
  90. stock_list_url = "https://www.banban.cn/gupiao/list_sz.html"
  91. # stock_info_url = "http://quote.eastmoney.com/sh" #sh上证 sz深圳
  92. stock_info_url = "http://quote.cfi.cn/quote_"
  93. output_file = "D://pythontest/files/gupiao/我的股票信息.csv"
  94. # slist = ['002656','002702','000001','000002']
  95. slist=[]
  96. getStockList(slist,stock_list_url)
  97. getStockInfo(slist,stock_info_url,output_file)

入库mysql封装的方法:

  1. import pymysql
  2. import logging
  3. import pandas as pd
  4. db_name = 'python'
  5. db_user = 'root'
  6. db_pass = 'root'
  7. db_ip = '127.0.0.1'
  8. db_port = 3306
  9. #写入数据到数据库中
  10. def writeDb(sql,db_data=()):
  11. """
  12. 连接mysql数据库(写),并进行写的操作
  13. """
  14. try:
  15. conn = pymysql.connect(db=db_name,user=db_user,passwd=db_pass,host=db_ip,port=int(db_port),charset="utf8")
  16. cursor = conn.cursor()
  17. except Exception as e:
  18. print(e)
  19. logging.error('数据库连接失败:%s' % e)
  20. return False
  21. try:
  22. cursor.execute(sql, db_data)
  23. conn.commit()
  24. except Exception as e:
  25. conn.rollback()
  26. logging.error('数据写入失败:%s' % e)
  27. return False
  28. finally:
  29. cursor.close()
  30. conn.close()
  31. return True
  32. #
  33. # sql = """ INSERT INTO user(email,last_name) VALUES(%s,%s) """
  34. # data = ("632443020@qq.com", "男")
  35. # result = writeDb(sql, data)
  36. sql = """ INSERT INTO stock_infos(stock_name,stock_code,jk,zs,zg,zd,hsl,syl) VALUES(%s,%s,%s,%s,%s,%s,%s,%s) """
  37. data = ("1","2","3","4","5","6","7","8") #直接写数字类型也能写入
  38. result = writeDb(sql, data)

Stocks信息表:

  1. CREATE TABLE
  2. stock_infos
  3. (
  4. id INT NOT NULL AUTO_INCREMENT COMMENT '主键',
  5. stock_name VARCHAR(30),
  6. stock_code VARCHAR(30),
  7. jk VARCHAR(10) COMMENT '今开',
  8. zs VARCHAR(10) COMMENT '昨收 ',
  9. zg VARCHAR(10) COMMENT '最高 ',
  10. zd VARCHAR(10) COMMENT '最低',
  11. hsl VARCHAR(10) COMMENT '换手率',
  12. syl VARCHAR(10) COMMENT '市盈率',
  13. PRIMARY KEY (id)
  14. )
  15. ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

 

爬取股票信息实现百分比进度条:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/379547
推荐阅读
相关标签
  

闽ICP备14008679号