前言:最近基金火热,此代码仅供学习娱乐,本人初学python,代码还有不少问题,鉴于能力有限,无法解决,希望各位大神多多指教。
目标:抓取编号,基本信息,评级, 夏普率等数据
所用模块:requests库,BeautifulSoup,re正则,协程模块,csv等
编写思路:requests库获取信息
BeautifulSoup和re正则清洗所需数据
csv 用于存储数据
time 计时与延时
gevent协程提速
话不多说,直接上代码
import requestsimport csvfrom bs4 import BeautifulSoupimport reimport geventfrom gevent import monkeyimport timefrom gevent.queue import QueueListtask=[] #协程工作列表Listallxiap2=['--','--'] #空列表用于补充xiapufundcode_List = [] #编号列表fundcodeurl_List2= [] #fund网址fundcodexiapu_List=[] #xiapu指标网址grade_List = [] #fund总信息列表grade_List1 = [] #写入列表存fund基本信息grade_List2 = [] #写入列表存fund评价grade_List3 = [] #写入列表存fundxiapgrade_List4 = [] #写入列表存fund编码keypointfund_List=[] #fund信息列列表xpandbzc_List=[] #xiapu和bzc信息列表xpandbzc_List2=[] #xiapu总列表sevengrade_List=[] #存评级headers = {"Referer": "http://fund.eastmoney.com/fund.HTML", "User-Agent": " " } #伪装代码,根据自己的ip进行添加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遍) returndef 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进行添加 headers2 = {"Referer": "http://fund.eastmoney.com/tsdata_"+"str(number_funds3)"+".HTML", "User-Agent": " " } #伪装代码,根据自己的ip进行添加 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) #信息添加进基本信息列表 for number_grade1 in number_grade: sevengrade=number_grade1.find_all('h3') #获得需要的评级 #print(sevengrade) for f in range(8): sevengrade2=sevengrade[f].text.replace("<h3>",' ') sevengrade3=sevengrade2.replace("</h3>",' ') #print(sevengrade3) sevengrade_List.append(sevengrade3) #print(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: passdef 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) returndef 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) for t in range(8): seve=sevengrade_List[t] grade_List2.append(seve) writer.writerow(grade_List2) returndef 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) for t in range(int(q)): a=int(8*t) b=int(8*t+8) fundcodexiap=xpandbzc_List2[t][a:b] grade_List3.append(fundcodexiap) writer.writerows(grade_List3) returnstart = 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:一直没找到为什么基金编码会重复抓三次的原因)
希望各位大神多多指教,第一次写代码,自知很多不足,还请指正!!!
总结以上是内存溢出为你收集整理的python 使用BeautifulSoup爬取天天基金网主要数据全部内容,希望文章能够帮你解决python 使用BeautifulSoup爬取天天基金网主要数据所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)