博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python爬虫之股票数据定向爬取
阅读量:2338 次
发布时间:2019-05-10

本文共 4349 字,大约阅读时间需要 14 分钟。

python爬虫之股票数据定向爬取

功能描述

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

前期分析

  • 选取原则:股票的信息静态存在HTML页面中,非js代码生成,没有robots协议限制
  • 选取方法:查看网页原码不纠结于某个网站,多找信息源尝试

没有成功,价格没有搜索到

在这里插入图片描述
在源码中搜索价格,不存在

在这里插入图片描述

搜索价格没有
在这里插入图片描述
没有找到相关的价格信息
在这里插入图片描述
没有找到相关价格信息
在这里插入图片描述

没有找到相关的价格信息

在这里插入图片描述
多此尝试之后,发现基本上都没有找到,于是找教程推荐的
百度股票,已经不见了
在这里插入图片描述

  • 总结:个人观点,股票价格这种实时更新的数据怎么会写在网页,大部分应该都是写在js中,然后又服务器发送相关数据,但是仍旧不失为一个练习的思路,还是来分析一下吧

教程提供的信息:

  • 关于单个股票的信息

    • 点击每个股票的连接,发现会出现相关的跳转,反映在网址上的变化就是多了几个关键字
    • 思路:获取每个股票的标号,输入到对应的网址中,即可获得相关股票的实时价格

在这里插入图片描述

  • 通过东方财富网获取所有股票的序号

在这里插入图片描述

  • 东方财富网的股票的序号

从图上就可以看出,是在对应的a标签中,可以采用正则表达式进行筛选r’[zh|sh]\d{6}’

在这里插入图片描述

程序编写

  • 第一步,编写相关的整体步骤
    • 从东方财富网获取股票的列表 getHTMLText(url)
    • 根据股票列表逐个到百度股票中获取个股的信息 getStockList(lst,stockURL)
    • 将结果存储到文件中 getStockInfo(lst,stockURL,fpath)
    • main函数将所有的函数连接起来
import requestsimport refrom bs4 import BeautifulSoup# 获取相关网页的html文件def getHTMLText(url):    return''# 获取所有股票的序号def getStockList(lst,stockURL):    return ''# 获取所有股票的价格def getStockInfo(lst,stockURL,fpath):    return ''def main():    stock_list_url = 'http://quote.eastmony.com/stocklist.html'    # 获取股票信息序号的网站    stock_info_url = 'https://gupiao.baidu.com/stock/'    # 获取单个股票的价格的网页    output_file = 'D://SpiderTest//BaiduStockInfo.txt'    # 文件保存的连接    slist = []    getStockList(slist,stock_info_url)    getStockInfo(slist,stock_info_url,output_file)    main()
  • 第二步,逐步完善各个步骤

    • 总是必须的获取相关页面的代码
def getHTMLText(url):    try:        r = requests.get(url)        r.raise_for_status()        r.encoding = r.apparent_encoding        return r.text    except:        return''
  • 获取相关的股票列表

这里有值得学习的东西,先获取所有的a标签,然后再逐个进行排除,如果是a标签,那就添加,不是那就跳过当前的循环,学会用try——except语句

def getStockList(lst,stockURL):    html =  getHTMLText(stockURL)    soup = BeautifulSoup(html,'html.parser')    a = soup.find_all('a')    for i in  a:        try:            href = i.attrs['href']            lst.append(re.findall(r'[s][hz]\d{6}',href))        except:            continue
  • 获取相关股票实时信息并将之写入相关的文件
def getStockInfo(lst,stockURL,fpath):    count = 0    for stock in lst:        # 遍历所有的股票编码列表        url = stockURL + stock + '.html'        # 生成么一个股票特定的网页的信息        html = getHTMLText(url)        try :            if html == '':                # 如果没有获取到相关网页信息,说明网页没有意义,那就跳过当前的循环                continue            infoDict = {
} # 创建对应的字典容器,将存储股票序号——价格的键值对信息 soup = BeautifulSoup(html,'html.parser') # 获取对应的网页的信息 stockInfo = soup.find('div',attrs={
'class':'bets-name'}) # 结合属性和名称,获取特定的标签 name = stockInfo.find_all(attrs={
'class':'bets-name'})[0] infoDict.update({
'股票名称':name.text.split()[0]}) keyList = stockInfo.find_all('dt') valueList = stockInfo.find_all('dd') for i in range(len(keyList)): key = keyList[i].text val = valueList[i].text infoDict[key] = val with open(fpath,'a',encoding = 'utf-8') as f: f.write(str(infoDict) + '\n') except: traceback.print_exc() continue
  • 这里写的还是很好看的,分析一下,首先,看下图,百度股市通中,某单股的原码
  • 清晰可见,关于股票的信息都在对应的< div > … < /div >标签中,并且属性中的class是极特殊的class = ‘stock-bets’的
  • 而在< div > … < /div >的标签中的,a标签的值在对应的就是对应的信息,不同的信息他的属性又是不同
  • 在其子标签中dt和dd标签有都含有所有与该股票相关的信息
    在这里插入图片描述
  • 第一步,先获取最外层最特殊的div标签,并且说明属性
stockInfo = soup.find('div',attrs={
'class':'stock-bets'}) # 结合属性和名称,获取特定的标签
  • 第二步,提取div标签的具有相关信息属性的标签,这个属性,就说明了这个标签代表的内容就是名字或者对应的信息
    • 注意:这里有一个注意点,这里标签的text属性,不是对应的string属性,text是输出所有的子节点和自身的string内容,用空格连接
      。string仅仅输出当前节点的string内容,如果有字节点,那就输出None
      详见 https://www.cnblogs.com/gl1573/archive/2018/11/14/9958716.html
name = stockInfo.find_all(attrs={
'class':'bets-name'})[0] infoDict.update({
'股票名称':name.text.split()[0]})
  • 第三步,提取所有的dd标签和dt标签,二者的数量相同,并作为键值对进行保存
keyList = stockInfo.find_all('dt')  valueList = stockInfo.find_all('dd')   for i in range(len(keyList)):         key = keyList[i].text         val = valueList[i].text         infoDict[key] = val
  • 第四步,采用IO流进行写入,注意类型的转换
with open(fpath,'a',encoding = 'utf-8') as f:                f.write(str(infoDict) + '\n')
  • 最后一步,就是异常的处理,调用traceback库,进行异常的处理
except:            traceback.print_exc()            continue
最后一步,代码的优化
  • 为了创造一个更好的用户体验,就创建了写入一个会实时显示进度的语块
count = count + 1  print('\r 当前进度:{:.2f}%'.format(count * 100 / len(lst)),end = "")

‘\r’会将输出的光标移到开头,覆盖原来的输出

总结
  • 关于搜索特定的标签,不仅仅是结合标签的名称,更是要结合标签的属性,通过属性和名称可以很好的对某一个标签进行定位
  • 关于try—except的处理,要知道引用traceback库函数,会反应出报错对的地方,不然不知道哪里出错很郁闷
  • 有一种设想,从一个网站爬取一定的数据或者项目序列,可以连续的爬取多个同类的网站
你可能感兴趣的文章
springcloud gateway
查看>>
drools使用记录
查看>>
阿里六面,挂在hrg,我真的不甘心!
查看>>
人生的康波周期,把握住一次,足以改变命运!
查看>>
互联网公司那些价值观-阿里巴巴
查看>>
去面试快手,问了我很多消息队列的知识!
查看>>
图解LeetCode No.18之四数之和
查看>>
402. Remove K Digits
查看>>
75. Sort Colors
查看>>
获取数组中前K小的数字
查看>>
数组heapify变为堆结构
查看>>
二叉树的非递归遍历
查看>>
218. The Skyline Problem
查看>>
Java PAT (Basic Level) Practice 写出这个数
查看>>
Python PAT (Basic Level) Practice 1016 部分A+B
查看>>
Python PAT (Basic Level) Practice 1006 换个格式输出整数
查看>>
Python PAT (Basic Level) Practice 1009 说反话
查看>>
Python PAT (Basic Level) Practice 1011 A+B 和 C
查看>>
Python PAT (Basic Level) Practice 1017 A除以B
查看>>
Python PAT (Basic Level) Practice 1042 字符统计
查看>>