资讯专栏INFORMATION COLUMN

python爬虫实战二——股票数据定向爬虫

icattlecoder / 2183人阅读

摘要:选取方法打开网页,查看源代码,搜索网页的股票价格数据是否存在于源代码中。将上述的代码封装成一个函数,对东方财富网页面解析的完整代码如下所示接下来是获得百度股票网链接描述单只股票的信息。

功能简介

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

说明

网站选择原则: 股票信息静态存在于html页面中,非js代码生成,没有Robbts协议限制。
选取方法: 打开网页,查看源代码,搜索网页的股票价格数据是否存在于源代码中。
如打开新浪股票网址:链接描述,如下图所示:

上图中左边为网页的界面,显示了天山股份的股票价格是13.06。右边为该网页的源代码,在源代码中查询13.06发现没有找到。所以判断该网页的数据使用js生成的,不适合本项目。因此换一个网页。

再打开百度股票的网址:链接描述,如下图所示:

从上图中可以发现百度股票的数据是html代码生成的,符合我们本项目的要求,所以在本项目中选择百度股票的网址。

由于百度股票只有单个股票的信息,所以还需要当前股票市场中所有股票的列表,在这里我们选择东方财富网,网址为:链接描述,界面如下图所示:

原理分析

查看百度股票每只股票的网址:https://gupiao.baidu.com/stock/sz300023.html,可以发现网址中有一个编号300023正好是这只股票的编号,sz表示的深圳交易所。因此我们构造的程序结构如下:

步骤1: 从东方财富网获取股票列表;

步骤2: 逐一获取股票代码,并增加到百度股票的链接中,最后对这些链接进行逐个的访问获得股票的信息;

步骤3: 将结果存储到文件。

接着查看百度个股信息网页的源代码,发现每只股票的信息在html代码中的存储方式如下:

因此,在我们存储每只股票的信息时,可以参考上图中html代码的存储方式。每一个信息源对应一个信息值,即采用键值对的方式进行存储。在python中键值对的方式可以用字典类型。因此,在本项目中,使用字典来存储每只股票的信息,然后再用字典把所有股票的信息记录起来,最后将字典中的数据输出到文件中。

代码编写

首先是获得html网页数据的程序,在这里不多做介绍了,代码如下:

#获得html文本
def getHTMLText(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

接下来是html代码解析程序,在这里首先需要解析的是东方财富网页面:链接描述,我们打开其源代码,如下图所示:

由上图可以看到,a标签的href属性中的网址链接里面有每只股票的对应的号码,因此我们只要把网址里面对应股票的号码解析出来即可。解析步骤如下:
第一步,获得一个页面:

html = getHTMLText(stockURL) 

第二步,解析页面,找到所有的a标签:

soup = BeautifulSoup(html, "html.parser") 
a = soup.find_all("a")

第三步,对a标签中的每一个进行遍历来进行相关的处理。处理过程如下:
1.找到a标签中的href属性,并且判断属性中间的链接,把链接后面的数字取出来,在这里可以使用正则表达式来进行匹配。由于深圳交易所的代码以sz开头,上海交易所的代码以sh开头,股票的数字有6位构成,所以正则表达式可以写为[s][hz]d{6}。也就是说构造一个正则表达式,在链接中去寻找满足这个正则表达式的字符串,并把它提取出来。代码如下:

for i in a:
    href = i.attrs["href"]
    lst.append(re.findall(r"[s][hz]d{6}", href)[0])

2.由于在html中有很多的a标签,但是有些a标签中没有href属性,因此上述程序在运行的时候出现异常,所有对上述的程序还要进行try...except来对程序进行异常处理,代码如下:

for i in a:
    try:
        href = i.attrs["href"]
        lst.append(re.findall(r"[s][hz]d{6}", href)[0])
    except:
        continue

从上面代码可以看出,对于出现异常的情况我们使用了continue语句,直接让其跳过,继续执行下面的语句。通过上面的程序我们就可以把东方财富网上股票的代码信息全部保存下来了。
将上述的代码封装成一个函数,对东方财富网页面解析的完整代码如下所示:

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)[0])
        except:
            continue

接下来是获得百度股票网链接描述单只股票的信息。我们先查看该页面的源代码,如下图所示:

股票的信息就存在上图所示的html代码中,因此我们需要对这段html代码进行解析。过程如下:
1.百度股票网的网址为:https://gupiao.baidu.com/stock/
一只股票信息的网址为:https://gupiao.baidu.com/stock/sz300023.html
所以只要百度股票网的网址+每只股票的代码即可,而每只股票的代码我们已经有前面的程序getStockList从东方财富网解析出来了,因此对getStockList函数返回的列表进行遍历即可,代码如下:

for stock in lst:
        url = stockURL + stock + ".html"

2.获得网址后,就要访问网页获得网页的html代码了,程序如下:

html = getHTMLText(url)

3.获得了html代码后就需要对html代码进行解析,由上图我们可以看到单个股票的信息存放在标签为div,属性为stock-betshtml代码中,因此对其进行解析:

soup = BeautifulSoup(html, "html.parser")
stockInfo = soup.find("div",attrs={"class":"stock-bets"})

4.我们又发现股票名称在bets-name标签内,继续解析,存入字典中:

infoDict = {}
name = stockInfo.find_all(attrs={"class":"bets-name"})[0]
infoDict.update({"股票名称": name.text.split()[0]})

split()的意思是股票名称空格后面的部分不需要了。

5.我们从html代码中还可以观察到股票的其他信息存放在dtdd标签中,其中dt表示股票信息的键域,dd标签是值域。获取全部的键和值:

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

6.最后把字典中的数据存入外部文件中:

with open(fpath, "a", encoding="utf-8") as f:
f.write( str(infoDict) + "
" )

将上述过程封装成完成的函数,代码如下:

def getStockInfo(lst, stockURL, fpath):
    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":"stock-bets"})
 
            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) + "
" )
        except:
            continue

其中try...except用于异常处理。

接下来编写主函数,调用上述函数即可:

def main():
    stock_list_url = "http://quote.eastmoney.com/stocklist.html"
    stock_info_url = "https://gupiao.baidu.com/stock/"
    output_file = "D:/BaiduStockInfo.txt"
    slist=[]
    getStockList(slist, stock_list_url)
    getStockInfo(slist, stock_info_url, output_file)
项目完整程序
# -*- coding: utf-8 -*-

import requests
from bs4 import BeautifulSoup
import traceback
import re
 
def getHTMLText(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""
 
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)[0])
        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":"stock-bets"})
 
            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) + "
" )
                count = count + 1
                print("
当前进度: {:.2f}%".format(count*100/len(lst)),end="")
        except:
            count = count + 1
            print("
当前进度: {:.2f}%".format(count*100/len(lst)),end="")
            continue
 
def main():
    stock_list_url = "http://quote.eastmoney.com/stocklist.html"
    stock_info_url = "https://gupiao.baidu.com/stock/"
    output_file = "D:/BaiduStockInfo.txt"
    slist=[]
    getStockList(slist, stock_list_url)
    getStockInfo(slist, stock_info_url, output_file)
 
main()

上述代码中的print语句用于打印爬取的进度。执行完上述代码后在D盘会出现BaiduStockInfo.txt文件,里面存放了股票的信息。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40716.html

相关文章

  • 爬虫框架Scrapy实战一——股票数据爬取

    摘要:技术路线爬虫框架语言由于在上一篇博客中已经介绍了股票信息爬取的原理,在这里不再进行过多介绍,如需了解可以参考博客链接描述,在本篇文章中主要讲解该项目在框架中如何实现。 简介 目标: 获取上交所和深交所所有股票的名称和交易信息。输出: 保存到文件中。技术路线:Scrapy爬虫框架语言: python3.5由于在上一篇博客中已经介绍了股票信息爬取的原理,在这里不再进行过多介绍,如需了解可以...

    Ilikewhite 评论0 收藏0
  • 首次公开,整理12年积累的博客收藏夹,零距离展示《收藏夹吃灰》系列博客

    摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

    Harriet666 评论0 收藏0
  • 【LeetCode】贪心算法--买卖股票的最佳时机 II(122)

    摘要:贪心算法每一步必须满足一下条件可行的即它必须满足问题的约束。四题目分析贪心算法,总是做出在当前看来是最好的选择,不从整体最优上加以考虑,也就是说,只关心当前最优解,按照贪心策略,不关心以后,我们只关心当前利益。 一、写在前面 为什么要在LeetCode刷题?大家都知道不管是校招还是社招算法题是必考题,而这一部分恰巧是大多数人的短板,所以刷题首先是为了提高自身的编程能力,能够在算法面试中...

    xbynet 评论0 收藏0
  • Python 网络爬虫实战:抖音短视频去水印爬虫详解

    摘要:我们知道,在抖音中下载到的视频是有水印的,这就催生出了很多抖音短视频去水印的解析网站,小程序等。禁止重定向,设置运行结果,是一个标签,便是重定向后的地址。 我们知道...

    hlcc 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<