python 使用BeautifulSoup爬取天天基金网主要数据

前言:最近基金火热,此代码仅供学习娱乐,本人初学python,代码还有不少问题,鉴于能力有限,无法解决,希望各位大神多多指教。

目标:抓取编号,基本信息,评级, 夏普率等数据

所用模块:requests库,BeautifulSoup,re正则,协程模块,csv等

编写思路:requests库获取信息
BeautifulSoup和re正则清洗所需数据
csv 用于存储数据
time 计时与延时
gevent协程提速

话不多说,直接上代码

import requests
import csv
from bs4 import BeautifulSoup
import re
import gevent
from gevent import monkey
import time
from gevent.queue import Queue
listtask=[]
 #协程工作列表
listallxiap2=['--','--']                                                                                                
#空列表用于补充xiapu
fundcode_list = []                                                                                                      
#编号列表
fundcodeurl_list2= []                                                                                                   
#fund网址
fundcodexiapu_list=[]                                                                                                   
#xiapu指标网址
grade_list1 = []                                                                                                        
#写入列表存fund基本信息
grade_list3 = []                                                                                                        
#写入列表存fundxiap
grade_list4 = []                                                                                                        
#写入列表存fund编码
keypointfund_list=[]                                                                                                    
#fund信息列列表
xpandbzc_list=[]                                                                                                        
#xiapu和bzc信息列表
xpandbzc_list2=[]                                                                                                       
#xiapu总列表
sevengrade_list=[]                                                                                                      
#存评级
sevengrade_list2=[]                                                                                                     
#存所有评级
headers = {"Referer": "http://fund.eastmoney.com/fund.html",
		           "User-Agent": "                                "#写入自己电脑ip 的user-agent
           }                                                                                                            
           #伪装
work = Queue()
def fundcode(p,e):                                                                                                        
#函数(funds的网站)
    res_funds=requests.get('http://fund.eastmoney.com/allfund.html',headers=headers)                                    
    #获取网站
    bs_funds=BeautifulSoup(res_funds.text.encode('ISO-8859-1').decode('gb18030'),'html.parser')                         
    #解析网站
    number_funds1=bs_funds.find('div',class_="data-list m_b").find_all('li')                                            
    #找funds编码路径
    for number_funds2 in number_funds1:
        number_funds3=number_funds2.find('a')
        number_funds5=str(number_funds3)
        r1 = re.findall('\d+', number_funds5)                                                                           
        #正则找编码
        fundcode_list.append(r1)
    fundcode_list5 = [x for x in fundcode_list if x != []]                                                              
    #删除空列表
    print(len(fundcode_list5))
    for i in range(p):                                                                                                  
    # 依次取出列表中fund编号
        try:
            number_funds3 =fundcode_list5[i+e][0]                                                     
            # 取出列表内的编号6500为一组,funds总数/2
            grade_list4.append(str(number_funds3))
            #print(str(number_funds3))
            url = 'http://fund.eastmoney.com/' + number_funds3 + '.html'                                                    
            #各个fund基本信息的网址
            xiapuurl='http://fundf10.eastmoney.com/tsdata_'+number_funds3+'.html'                                           
            #xiapu等信息的网址
            fundcodexiapu_list.append(xiapuurl)                                                                             
            #xiapu和bzc的信息网址存进列表
            fundcodeurl_list2.append(url)                                                                                   
            #单个fund的网址
        except IndexError:
            print("无数据")
    for s in range(p):
        try:
            fundcodeurl = fundcodeurl_list2[s]                                                                              
            # 从fundurl列表中提取网址
            xiapuurl1 = fundcodexiapu_list[s]                                                                               
            # 从fundxiapu列表中提取网址
            work.put_nowait(fundcodeurl)
            work.put_nowait(xiapuurl1)
        except IndexError:
            print("无数据")
    with open('D://python//items1//items//ttjj//ttjjbianhao.csv', 'w', encoding='utf-8-sig',newline='') as tt:          
    #打开新csv
        writer = csv.writer(tt)
        header = ['FUND编号']
        writer.writerow(header)
        writer.writerows(grade_list4)                                                                                   
        #写入编码进csv(编码有bug,会写入3遍)
    return
def fundall(p):
        for s in range(p):                                                                                              
        #设置网址个数
            time.sleep(1)
            fundcodeurl=fundcodeurl_list2[s]                                                                            
            #从fundurl列表中提取网址
            xiapuurl1=fundcodexiapu_list[s]                                                                             
            #从fundxiapu列表中提取网址
            headers1 = {"Referer": "http://fund.eastmoney.com/"+"str(number_funds3)"+".html",
                       "User-Agent":"                                "#写入自己电脑ip 的user-agent
                       }
            headers2 = {"Referer": "http://fund.eastmoney.com/tsdata_"+"str(number_funds3)"+".html",
                       "User-Agent": "                                "#写入自己电脑ip 的user-agent
                       }
            fundcodeurl=work.get_nowait()
            xiapuurl1=work.get_nowait()
            print(fundcodeurl)
            print(xiapuurl1)
            res_fundcodeurl=requests.get(fundcodeurl,headers=headers1)                                                   
            #基本信息网址代码
            bs_fundcodeurl=BeautifulSoup(res_fundcodeurl.text.encode('ISO-8859-1').decode('utf-8'),'html.parser')       
            #清洗代码
            number_grade=bs_fundcodeurl.find('li',class_="increaseAmount")                                              
            #未处理的基本信息
            fundscale0= bs_fundcodeurl.find('div',class_="infoOfFund")                                                  
            #未处理的基本信息
            res_xiapufundurl=requests.get(xiapuurl1,headers=headers2)                                                    
            #获取xiapu网址信息代码
            bs_xiapufindurl=BeautifulSoup(res_xiapufundurl.text,'html.parser')                                          
            #清洗代码
            xia1=bs_xiapufindurl.find('div',class_="box").find_all("tr")                                                
            #获取未处理的xia的信息
            for m in range(6):
                fundscale1=fundscale0.find_all('td')[m].text                                                            
                #获取基本的信息
                keypointfund_list.append(fundscale1)                                                                    
                #信息添加进基本信息列表
            #print(keypointfund_list)
            for number_grade1 in number_grade:
                sevengrade=number_grade1.find_all('h3')                                                                 
                #获得需要的评级
                for f in range(8):
                    sevengrade2=sevengrade[f].text.replace("<h3>",' ')
                    sevengrade3=sevengrade2.replace("</h3>",' ')
                    sevengrade_list.append(sevengrade3)
                sevengrade_list2.append(sevengrade_list)
            for xia2 in xia1:
                for k in range(2):
                    xia3=xia2.find_all(class_="num")[k].text                                                            
                    #获得xia的信息
                    xpandbzc_list.append(xia3)                                                                          
                    #将xia的信息存进xia的列表
            xpandbzc_list2.append(xpandbzc_list)
            #print(len(xpandbzc_list2[s]))
            print(((len(xpandbzc_list2[s]))+2)/8)
            if (len(xpandbzc_list2[s])<8*(s+1)):
                xpandbzc_list2[s].extend(listallxiap2)
            else:
                pass
        #print(sevengrade_list2)

def open1():
    with open('D://python//items1//items//ttjj//ttjj1.csv','w',encoding='utf-8-sig',newline='') as tt:                       
    #打开csv存基本信息
        writer=csv.writer(tt)
        header=['基金类型','基金规模','基金经理','成 立 日','管 理 人','基金评级']
        writer.writerow(header)
        for t in range(int(q)):
            a=int(6*t)
            b=int (6*t+6)
            keypo1=keypointfund_list[a:b]
            grade_list1.append(keypo1)
        writer.writerows(grade_list1)
    return
def open2():
    with open('D://python//items1//items//ttjj//ttjj2.csv','w',encoding='utf-8-sig',newline='') as tt:
        writer=csv.writer(tt)
        header=['近一周','近一月','近三月','近六月','今年来','近一年','近两年','今年来']
        writer.writerow(header) 
        #写入header
        for t in range(int(q)):
        #t个fund
            a=int(8*t)  
            #此列表有些问题 列表里面的分列表有q个
            b=int(8*t+8)
            seve=sevengrade_list2[t][a:b]
            #取出数据
            writer.writerow(seve)#写入csv中
    return
def open3():
    with open('D://python//items1//items//ttjj//ttjj3.csv','w',encoding='utf-8-sig',newline='') as tt:
        writer=csv.writer(tt)
        header=[' ','','标准差(近一年)','标准差(近两年)','夏普率(近一年)','夏普率(近两年)','信息比率(近一年)','信息比率(近两年)']
        writer.writerow(header)
        #写入header
        for t in range(int(q)):
            a=int(8*t)
            #此列表有些问题 列表里面的分列表有q个
            b=int(8*t+8)
            fundcodexiap=xpandbzc_list2[t][a:b]
            grade_list3.append(fundcodexiap)
            #取出数据
        writer.writerows(grade_list3)
        #写入csv中
    return


start = time.time()
q=input("请输入总数funds个数:")
e=input("请输入已抓取的总数:")
#因为没有ip代理池,避免封ip,采取多次抓取数据


fundcode(int(q),int(e))
for l in range(2):
    task=gevent.spawn(fundcode(int(q),int(e)))
    listtask.append(task)
gevent.joinall(listtask)
fundall(int(q))
open1()
open2()
open3()
end = time.time()
print(start-end)

在这里插入图片描述

经过手动处理的效果图,勉强完成目标
最后:
此程序无ip代理池,需要多次分开抓取,
无多线程,运行极慢,
数据抓入csv后需要手动处理,为避免出现IndexError空列表错误,需要在csv删除最后重复的基金编码数据
(ps:一直没找到为什么基金编码会重复抓三次的原因)

希望各位大神多多指教,第一次写代码,自知很多不足,还请指正!!!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值