功能:

通过程序实现从基金列表页,获取指定页数内所有基金的近一周收益率以及每支基金的详情页链接。再进入每支基金的详情页获取其余的基金信息,将所有获取到的基金详细信息按近6月收益率倒序排列写入一个Excel表格。

思路:

  1. 通过实例化Tiantian_spider类的对象,初始化一个PhantomJS浏览器对象

  2. 使用浏览器对象访问天天基金近六月排行的页面,获取该页面的源码

  3. 从源码从获取每支基金所在的行(可以指定要获取基金的页数)

  4. 从每行中获取每支基金的近1周收益率和基金详情链接

  5. 获取到每个基金的详情链接后,使用多进程分别进入每支基金的详情页面

  6. 进入详情页后,获取基金的相关信息,并存入列表

  7. 将从所有基金的基金详情与在列表页获取的基金近1周收益率拼接后存入列表

  8. 再将所有信息写入Excel表格

  1from selenium import webdriver2from lxml import etree3import time4from openpyxl import Workbook5import multiprocessing6import re78class Tiantian_spider():9   def __init__(self):10       self.driver = webdriver.PhantomJS()      #指定的PhantomJS浏览器创建浏览器对象11       self.html = None12       self.next_page = True13       self.fund_url_list = []141516    #1 发起请求17   def parser_url(self):18       # if self.next_page :19       # 点击页面进行翻页20       # label[last()]---》定位到最后一个label,即<label value="xx">下一页</label>21       # last()是一个函数,表示取最后一个22       self.driver.find_element_by_xpath("//div[@id='pagebar']/label[last()]").click()23       time.sleep(4)  # 网页返回数据需要时间24       self.html = self.driver.page_source252627   def parser_data_for_url(self):28       '''从基金列表页获取每支基金的近一周收益和详情链接'''29       # 解析字符串格式的HTML文档对象,将传进去的字符串转变成_Element对象30html = etree.HTML(self.html)31       tr_list = html.xpath("//table[@id ='dbtable']//tbody/tr")32       next_page = html.xpath("//div[@id ='pagebar']//label[last()]")33       for tr in tr_list:34           tds =tr.xpath("./td")35           # 将近一周收益和详情链接组成的元组加入fund_url_list列表36           self.fund_url_list.append((str(tds[8].text),str(tds[2].xpath("./a/@href")[0])))3738       return next_page    # 返回下一页3940    #翻页控制器41   def over_page(self,next_page):42       # 获取最后一页43       kw = next_page[0].xpath("./label[contains(@class,'end')]")44       # print(kw)45       # 判断是否是最后一页,如果是,则返回False,否则返回True46       flag = True if len(kw)==0 else False47       return flag4849   def get_every_fund_url(self, url, page):50       # page:要获取前多少页的基金数据51       # 1 发起请求52       # 2 获取数据,解析数据53       self.driver.get(url)54       self.html = self.driver.page_source55       # 当页数不为0且还有下一页时,执行下面的操作56       while page > 0 and self.next_page:57           next_page= self.parser_data_for_url()58           # 4 翻页继续爬取59           self.next_page = self.over_page(next_page)60           # 如果不是下一页,就继续翻页61           if self.next_page:62                self.parser_url()63           page -= 164       # 返回每支基金近一周收益和详情链接65       return self.fund_url_list666768   def close_driver(self):69       self.driver.quit()707172def save_data(data):7374   wb = Workbook()     # 新创建一个文件75   ws = wb.active                 # 获取当前正在运行的工作表/激活工作表76    #将数据一行一行插入到工作表中77    #列表第一个元素将作为标题78   for i in data:79       ws.append(i)80   wb.save("近6月基金排名_" + time.strftime('%Y%m%d%H%M%S')+".xlsx")818283# 多进程任务函数84# 获取进入基金的详情页获取详细信息85def run(url, nearly_1_week):8687   driver = webdriver.PhantomJS()88   driver.get(url)    89   page_html = etree.HTML(driver.page_source)  # 获取页面源码90    #获取基金名称91    #通过xpath或者的是一个元素列表,要元素下面的子元素,需要取某个具体的元素,不能用列表取92   fund_name =page_html.xpath("//div[@class='fundDetail-tit']/div/text()")[0]93    #获取基金代码类名94   fund_code_class_name = page_html.xpath("//div[@class='fundDetail-tit']/div/span[last()]/@class")[0]95    #根据代码类名判断基金代码只有一个,还是有前后端两个96   if fund_code_class_name == "ui-num":97       fund_code = page_html.xpath("//div[@class='fundDetail-tit']/div/span[last()]/text()")[0]98   elif fund_code_class_name == "fundcodeInfo":99       fund_code_info = page_html.xpath("//div[@class='fundDetail-tit']/div/span[@class='fundcodeInfo']")[0]
100       fund_code =  "前端: " +fund_code_info.xpath("./span[1]/text()")[0] + "    后端: " + fund_code_info.xpath("./span[2]/text()")[0]
101
102    #收益和净值所在的上层div
103   data_of_fund = page_html.xpath("//div[@class='dataOfFund']")[0]
104    #近1月
105   nearly_1_month =data_of_fund.xpath("./dl[1]/dd[2]/span[last()]/text()")[0]
106    #近1年
107   nearly_1_year =data_of_fund.xpath("./dl[1]/dd[3]/span[last()]/text()")[0]
108    #日期
109   date = data_of_fund.xpath("./dl[2]/dt/p/text()")[0]
110   date = re.findall(r"(\d{4}-\d{2}-\d{2})", date)[0] ifre.findall(r"(\d{4}-\d{2}-\d{2})", date) else ""
111    #单位净值
112   unit_net_worth =data_of_fund.xpath("./dl[2]/dd[1]/span[1]/text()")[0]
113    #日增长率
114   daily_growth_rate =data_of_fund.xpath("./dl[2]/dd[1]/span[2]/text()")[0]
115    #近3月
116   nearly_3_month =data_of_fund.xpath("./dl[2]/dd[2]/span[last()]/text()")[0]
117    #近3年
118   nearly_3_year =data_of_fund.xpath("./dl[2]/dd[3]/span[last()]/text()")[0]
119    #累计净值
120   accumulated_net =data_of_fund.xpath("./dl[3]/dd[1]/span[1]/text()")[0]
121    #近6月
122   nearly_6_month =data_of_fund.xpath("./dl[3]/dd[2]/span[last()]/text()")[0]
123    #基金成立日
124   since_established =data_of_fund.xpath("./dl[3]/dd[3]/span[last()]/text()")[0]
125    #获取基金类型,风险程度,规模等信息所在的上层vid
126   fund_info_item =page_html.xpath("//div[@class='infoOfFund']")[0]
127    #获取基金的类型以及风险程度
128   fund_type = fund_info_item.xpath(".//tr[1]/td[1]/a/text()")[0]
129   fund_risk =fund_info_item.xpath(".//tr[1]/td[1]/text()")[1].split()[-1].strip()
130    #获取基金规模
131    fund_scale =fund_info_item.xpath(".//tr[1]/td[2]/text()")[0].split(":")[-1]
132    #获取基金经理
133   fund_manager =fund_info_item.xpath(".//tr[1]/td[3]/a/text()")[0]
134    #获取基金成立日
135   establishment_date =fund_info_item.xpath(".//tr[2]/td[1]/text()")[0].split(":")[-1]
136    #获取管理人
137   administrator =fund_info_item.xpath(".//tr[2]/td[2]/a/text()")[0]
138    #获取评级类名
139   fund_rating_class_name =fund_info_item.xpath(".//tr[2]/td[3]/div/@class")[0]
140   data_list = []
141    #将每支基金的详细信息拼接成一个列表,并返回
142   data_list.append(str(fund_code))
143   data_list.append(str(fund_name))
144   data_list.append(str(date))
145   data_list.append(str(unit_net_worth))
146   data_list.append(str(accumulated_net))
147   data_list.append(str(daily_growth_rate))
148   data_list.append(str(nearly_1_week))
149   data_list.append(str(nearly_1_month))
150   data_list.append(str(nearly_3_month))
151   data_list.append(str(nearly_6_month))
152   data_list.append(str(nearly_1_year))
153   data_list.append(str(nearly_3_year))
154   data_list.append(str(since_established))
155
156    #根据评级所在divid的类名判断当前基金是几星
157   if fund_rating_class_name == 'jjpj1':
158       data_list.append("一星")
159   elif fund_rating_class_name == "jjpj2":
160       data_list.append("二星")
161   elif fund_rating_class_name == "jjpj3":
162       data_list.append("三星")
163   elif fund_rating_class_name == "jjpj4":
164       data_list.append("四星")
165   elif fund_rating_class_name == "jjpj5":
166       data_list.append("五星")
167   else:
168       data_list.append("暂无评级")
169
170   data_list.append(fund_type + " | " + fund_risk)
171   data_list.append(str(fund_scale))
172   data_list.append(str(fund_manager))
173   data_list.append(str(establishment_date))
174   data_list.append(str(administrator))
175
176    driver.quit()   # 关闭浏览器
177   return data_list
178
179
180if __name__ == '__main__':
181
182   start = time.time()
183    #基金排行按近6月排行页面url
184   url ="http://fund.eastmoney.com/data/fundranking.html#tall;c0;r;s6yzf;pn50;ddesc;qsd20200725;qed20210725;qdii;zq;gg;gzbd;gzfs;bbzt;sfbb"
185   tiantian = Tiantian_spider()    # 实例化Tiantian_spider类
186    #获取每个基金的近1周收益和基金详情链接
187    #传入参数为排行页面url和要获取数据的总页数
188    url_list = tiantian.get_every_fund_url(url,4)
189
190    #要获取的数据,也作为保存excel的标题
191   data = [["基金代码", "基金简称", "日期", "单位净值", "累计净值", "日增长率", "近一周", "近1月", "近3月", "近6月", \
192       "近1年", "近3年", "成立来", "基金评级", "基金类型", "基金规模", "基金经理", "成立日", "管理人"]]
193
194   result = []
195    #multiprocessing.cpu_count():获取cpu核数
196    #新建一个进程池,最大放cpu核数个进程
197   pool = multiprocessing.Pool(multiprocessing.cpu_count())
198   for nearly_1_week, url in url_list:
199       # pool.apply_async:异步执行,10个任务同时执行
200       # 通过进程池来执行并发任务
201       # 进程池会自动找不同个数的进程来执行任务函数run, 将args=(url, nearly_1_week)中的url, nearly_1_week两个参数传入run函数
202       # .get()表示获取任务函数的返回值,即基金的详细信息
203       result.append(pool.apply_async(func=run, args=(url,nearly_1_week)).get())
204
205   pool.close()    # 关闭进程池
206   pool.join()     # 阻塞进程,所有进程池中的任务都执行完毕了,才能继续执行主进程
207    #将基金列表按基金的近6月收益率倒序排列后加入data
208   data.extend(sorted(result, key=lambda x:x[9], reverse=True))
209   save_data(data)
210   end = time.time()
211   print("耗时为:%s秒" % (end - start))

本文小练习爬取的数据均为公开数据,并且仅限于技术研究,不给网站造成负担。请大家在练习的时候注意合法合规!


最后: 大家可以去我公众号:伤心的辣条 ! 进去有许多资料共享!资料都是面试时面试官必问的知识点,也包括了很多测试行业常见知识,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。


好文推荐

转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!

面试经:一线城市搬砖!又面软件测试岗,5000就知足了…

面试官:工作三年,还来面初级测试?恐怕你的软件测试工程师的头衔要加双引号…

什么样的人适合从事软件测试工作?

那个准点下班的人,比我先升职了…

测试岗反复跳槽,跳着跳着就跳没了…

学会这个技能,让你的Fitnesse锦上添花相关推荐

  1. 参加web前端培训要学会哪些技能

    想要成为一名合格的web前端程序猿,要学习的东西有很多,那么参加web前端培训要学会哪些技能呢?来看看下面的详细介绍就知道了. 参加web前端培训要学会哪些技能?想从事web前端开发,只会HTML.C ...

  2. 一个合格的web前端程序员要学会哪些技能?

    想要成为一名合格的web前端程序猿,要学习的东西有很多,那么web前端要学会哪些技能呢?来看看下面的详细介绍就知道了. 一个合格的web前端程序员要学会哪些技能?想从事web前端开发,只会HTML.C ...

  3. 数据分析师薪资待遇如何呢?需要学会哪些技能?

    不得不说,数据分析行业如今正朝着前所未有的蓬勃的态势发展.据拉勾网统计,全国有大量的数据分析岗位,亟待专业人才填补空缺.其中,有一半都分布在一线和新一线城市,尤其以北上广深和杭州为主. 那么,为什么国 ...

  4. 让机器人学会社交技能

    机器人可以在大学校园里运送食物,在高尔夫球场上打出一杆进洞,但即使是最复杂的机器人也不能进行对人类日常生活至关重要的基本社会互动. 麻省理工学院的研究人员现在已将某些社交互动纳入机器人的框架,使机器能 ...

  5. 大学要学的计算机技能,除了学习专业知识,大学生还应该学会什么技能?

    大学生学习自己的专业知识是最基本的要求.但是大学四年是一个自我管理的过程,与高中时老师天天盯着不动,大学有更多的自主时间,因此,除了专业知识的学习,大学生还应该充分利用大学时光学习其他的技能: 第一, ...

  6. 学会这个技能,副业加 1 万不是问题,30 本理财秘籍免费领取(速领)

    ★ 如果你没找到一个当你睡觉时还能挣钱的方法,你将工作到死.--巴菲特 前言 最近因为这个新型冠状病毒,大家在家里有没有学习 ?是不是发霉了呢,或者像如下这状态 ? 或者这样的: 我管你是不是呢! 不 ...

  7. 程序员,学会这些技能让你的薪资翻倍!

    话不多说,直接上图更直观! 这是2019年程序员年薪状况图,从图中可以看到程序员的年薪呈正态分布,一半人集中在10-20万之间.年薪在5-10万的程序员占比为13.3%,年薪在20-25万的程序员占比 ...

  8. 作为一个php程序员要学会的技能

    2019独角兽企业重金招聘Python工程师标准>>> HTML/CSS/JavaScript 这些就不必说了,入门级WEB开发程序员都要掌握的. 其次说说PHP编程能力,精通PHP ...

  9. 【安全专业能力】关于一个安全人员必须要学会的技能

    文章目录 前言 技能分类 1. 安全管理类知识和技能 1)法律法规 2)认证 2. 安全技术类知识和技能 1) 物理环境安全 2) 网络安全 3) 系统安全 4) 应用安全 5) 数据安全 6) 终端 ...

最新文章

  1. Apache Common HttpClient使用之七种武器
  2. android万年历有什么作用,基于android的万年历农历怎么算
  3. asp创建mysql表_asp创建数据库表
  4. java 读文件夹_java怎么读取读取文件夹下的所有文件夹和文件?
  5. java channelexec_java-使用SSH exec通道调用Shell脚本,但忽略对其他Shell脚本的调用
  6. 现在还有没有人不学 Python 的?
  7. 什么是U-Boot以及如何下载U-Boot源码
  8. 第一轮返工潮,哪些城市疫情传播压力最大
  9. AbstractSyntax Tree (AST)
  10. Win10:ssh报错:RSA host key for 192.168.3.10 has changed and you have requested strict checking.
  11. CFree注册码及破解过程【转】
  12. mshtml 解析html c,使用MSHTML解析HTML代码
  13. php小米官网,小米商城的首页
  14. 苹果雪豹操作系统正式版_苹果放出iOS 13andiPadOS beta 2:加入SMB网络共享、APFS硬盘支持...
  15. ipersistfile save 失败 错误代码“0x80070005” 拒绝访问的解决办法
  16. 部分可重构系统中可能发生的几个不良现象及解决方法(解耦) Xilinx FPGA DFX Partial Reconfig Decouple
  17. 数据分析--企业的贤内助 附下载地址
  18. 单工通信模式、半双工通信模式和全双工通信模式的区别
  19. 卡特兰数Catalan
  20. 【获奖公布】“我的2016”主题征文活动

热门文章

  1. 编译 php7,编译PHP7
  2. freemarker ftl模板_Web开发人员必会的模板引擎技术之Freemarker
  3. spring bean加载过程_Spring的Bean加载容器机制
  4. python输出输入的字符串_python笔记3-输出输入、字符串格式化
  5. 基于机器视觉的铁片轮廓检测
  6. Python Imaging Library:ImageDraw Module(图像绘制模块)
  7. 微信小程序创建一个新项目
  8. PHP-FPM,Nginx,FastCGI 之间的关系
  9. 通过分区(Partitioning)提高Spark的运行性能
  10. iOS 推送通知详解