栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

如何用python爬取新浪财经

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何用python爬取新浪财经

通过python爬取新浪财经的股票历史成交明细 要求

通过新浪财经爬取历史数据:http://market.finance.sina.com.cn/transHis.php?symbol=sz000001&date=2021-04-27&page=60
要求:输入日期和股票代码后将一天所有的记录存入一个csv文件,并打印输出当日股票的最大值,最小值和平均值

首先我们可以观察到股票的名字就是symbol参数,日期就是date参数,而page有很多页。假若我们需要爬取一整日的信息,我们就需要找到page的首页和尾页。但是每支股票每天的首页和尾页可能数字都不同,所以这个地方是难点,我们需要用if去判断是否已经到尾页。

导入库
import requests
import time
from bs4 import BeautifulSoup
import csv
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36 FS"}
# 全局定义一个listone列表用于之后存放爬取的信息
listone = []
输入想要的信息
def main():
    #gupiao = input("请输入你想要查询的股票(例如sz000001):")
    #date = input("请输入你想要查询的日期(格式为2021-04-27):")

    # 这里的小代码我其实是为了测试以下尾页的停止,因为这个例子股票的日期在77页为尾页,80页说明flag为0
    # flag = gethtml('sz000001', '2021-04-27', 80)
    
    
    # 一般来讲股票不太可能超过100页。我们这里取一个上限值就好
    # 后续如果碰到尾页会之间break跳出循环不会到100页
    for i in range(1,100):
        # 早期为了不每次都手动输入可以直接先写定参数,后期再加入input
        # 返回如果是0则说明爬取错误或者到达尾页,要跳出循环
        flag = gethtml('sz000001','2021-04-27',i)
        # 最好需要间隔5s,否则太快爬取会被新浪封ip
        time.sleep(5)
        
        if flag==0:# 返回如果是0则说明爬取错误或者到达尾页,要跳出循环
            break
    #打印全局我们爬取数组保存在的listone数组里
    print(listone)
    #保存如csv
    save_csv(listone)
    # compute()
main()
获取请求页面html
def gethtml(gupiao,date,page):
    # 拼接字符串url
    url = 'https://market.finance.sina.com.cn/transHis.php?symbol='+gupiao+'&date='+date+'&page='+str(page)
    # 打印访问url,方便后期查看进度
    print(url)
    try:
        # request发送get请求
        r = requests.get(url=url,headers=headers)
        # None
        r.raise_for_status()
        # print("text的状态:",r.raise_for_status())
        r.encoding = r.apparent_encoding
        # 其实这里不管是不是尾页或是超过尾页text的状态都是none,都可以访问区别只是有没有数据而已
        
        # 所以这里我们无法根据request请求判断是否尾页,我们需要更进一层判断,即获取页面其中内容get_message
        flag = get_message(r.text,page)
        if flag == 0:
            #如果get_message返回给我们的为0则说明真的出现错误或者到达尾页flag为0,需要终止跳出循环了。
            return 0
    except Exception as result:
        print("错误原因:",result)
        return 0

分析r.text内容同时判断是否尾页

正常数据:

超过尾页tbody为空:

def get_message(text,page):
    # 煮一碗soup
    soup = BeautifulSoup(text, 'lxml')
    # 这里我们可以打印看到如果是有数据的tbody里面会有内容,那么soup.tbody.string会为none
    # 但是如果是已经尾页没有数据的tbody里面会没有内容,那么soup.tbody.string会为空字符串
    # 我们可以根据这个区别来判断是否已经超过尾页
    # print(soup.tbody.string)

    if soup.tbody.string!=None:
        # 如果不是None说明tbody为空,已经爬取到尾页为空了
        # 此时打印到头信息,然后return 0告诉上一层并跳出循环停止爬取
        print('到头为空')
        return 0
    else:
        # 我们可以观察他整个tbody的结构,发现他的数据包含在tbody的每一个tr内
        # 对tbody里所有的tr进行遍历
        for each in soup.tbody.find_all('tr'):
            # 打印查看each内容
            # print(each)
            # 获取each内的th和td标签
            th = each.select('th')
            td = each.select('td')
            # 根据索引获取到th内的信息,并放入listtwo中
            listtwo = [th[0].string,td[0].string,td[1].string,td[2].string,td[3].string,th[1].contents[0].string]
            # print(listtwo)
            # 最后将listtwo添加入listone的末尾
            listone.append(listtwo)

< td >和< th >标签内的索引内容:

保存入csv文件
def save_csv(list):
    print("list",list)
    with open('sina.csv', 'w',newline='', encoding='utf-8-sig') as f:
        wr = csv.writer(f)
        # 标题头
        wr.writerow(['成交时间','成交价','价格变动','成交量(手)','成交额(元)','性质'])
        # 把listone里所有爬取的数据写入csv文件
        wr.writerows(listone)
    f2.close()

求取平均值最大值最小值
def compute():
    with open('sina.csv','r',encoding='utf-8-sig') as f2:
        r = csv.reader(f2)
        #跳过表头的文字
        head = next(r)
        sum = 0
        max = 0
        min=100
        count = 0
        for row in r:
            # print(row)
            thisnum = float(row[1])
            sum = sum + thisnum
            if max thisnum :
                min = thisnum
            count= count+1
        avg = sum/count
        print("最大值为",max)
        print("最小值为",min)
        print("平均值为",avg)
  	f2.close()
  • 留个坑有机会用panda库进行计算
整体代码
import requests
import time
from bs4 import BeautifulSoup
import csv
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36 FS"}
# 全局定义一个listone用于之后存放爬取的信息
listone = []

def get_message(text,page):
    # 煮一碗soup
    soup = BeautifulSoup(text, 'lxml')
    # 这里我们可以打印看到如果是有数据的tbody里面会有内容,那么soup.tbody.string会为none
    # 但是如果是已经尾页没有数据的tbody里面会没有内容,那么soup.tbody.string会为空字符串
    # 我们可以根据这个区别来判断是否已经超过尾页
    # print(soup.tbody.string)

    if soup.tbody.string!=None:
        # 如果不是None说明tbody为空,已经爬取到尾页为空了
        # 此时打印到头信息,然后return 0告诉上一层并跳出循环停止爬取
        print('到头为空')
        return 0
    else:
        # 我们可以观察他整个tbody的结构,发现他的数据包含在tbody的每一个tr内
        # 对tbody里所有的tr进行遍历
        for each in soup.tbody.find_all('tr'):
            # 打印查看each内容
            # print(each)
            # 获取each内的th和td标签
            th = each.select('th')
            td = each.select('td')
            # 根据索引获取到th内的信息,并放入listtwo中
            listtwo = [th[0].string,td[0].string,td[1].string,td[2].string,td[3].string,th[1].contents[0].string]
            # print(listtwo)
            # 最后将listtwo添加入listone的末尾
            listone.append(listtwo)

# 返回0则说明不存在页面  sz000001
def gethtml(gupiao,date,page):
    # 拼接字符串url
    url = 'https://market.finance.sina.com.cn/transHis.php?symbol='+gupiao+'&date='+date+'&page='+str(page)
    # 打印访问url,方便后期查看进度
    print(url)
    try:
        r = requests.get(url=url,headers=headers)
        # None
        r.raise_for_status()
        # print("text的状态:",r.raise_for_status())
        r.encoding = r.apparent_encoding
        # 其实这里不管是不是尾页或是超过尾页text的状态都是none,都可以访问区别只是有没有数据而已
        # 所以这里我们无法根据request请求判断是否尾页,我们需要更进一层判断,即获取页面其中内容get_message

        flag = get_message(r.text,page)
        if flag == 0:
            #如果get_message返回给我们的为0则说明真的出现错误或者到达尾页flag为0,需要终止跳出循环了。
            return 0
    except Exception as result:
        print("错误原因:",result)
        return 0


def save_csv(list,gupiao,date):
    print("list",list)
    with open('sina'+gupiao+date+'.csv', 'w',newline='', encoding='utf-8-sig') as f:
        wr = csv.writer(f)
        wr.writerow(['成交时间','成交价','价格变动','成交量(手)','成交额(元)','性质'])
        wr.writerows(listone)
    f.close()

def compute(gupiao,date):
    with open('sina'+gupiao+date+'.csv','r',encoding='utf-8-sig') as f2:
        r = csv.reader(f2)
        head = next(r)
        sum = 0
        max = 0
        min=100
        count = 0
        for row in r:
            # print(row)
            thisnum = float(row[1])
            sum = sum + thisnum
            if max thisnum :
                min = thisnum
            count= count+1
        avg = sum/count
        print("最大值为",max)
        print("最小值为",min)
        print("平均值为",avg)
   f2.close()

def main():
    gupiao = input("请输入你想要查询的股票(例如sz000001):")
    date = input("请输入你想要查询的日期(格式为2021-04-27):")
    # 早期为了不每次都手动输入可以直接先写定参数,后期再加入input
    # 这里我其实是为了测试以下尾页的停止
    # flag = gethtml('sz000001', '2021-04-27', 80)
    # 一般来讲股票不太可能超过100页。我们这里取一个上限值就好
    # 后续如果碰到尾页会之间break跳出循环不会到100页
    for i in range(1,100):
        # 返回如果是0则说明爬取错误或者到达尾页,要跳出循环
        flag = gethtml(gupiao,date,i)
        # 最好需要间隔5s,否则太快爬取会被新浪封ip
        time.sleep(5)
        if flag==0:
            break
    print(listone)
    save_csv(listone,gupiao,date)
    #计算股票单价平均值最大值最小值
    compute(gupiao,date)
main()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/303339.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号