实战+代码!Selenium + Phantom JS爬取天天基金数据

 

功能:

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

思路:

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

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

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

图片

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

图片

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

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

图片

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

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

图片

  1. from selenium import webdriver

  2. from lxml import etree

  3. import time

  4. from openpyxl import Workbook

  5. import multiprocessing

  6. import re

  7. class Tiantian_spider():

  8. def __init__(self):

  9. self.driver = webdriver.PhantomJS() #指定的PhantomJS浏览器创建浏览器对象

  10. self.html = None

  11. self.next_page = True

  12. self.fund_url_list = []

  13. #1 发起请求

  14. def parser_url(self):

  15. # if self.next_page :

  16. # 点击页面进行翻页

  17. # label[last()]---》定位到最后一个label,即<label value="xx">下一页</label>

  18. # last()是一个函数,表示取最后一个

  19. self.driver.find_element_by_xpath("//div[@id='pagebar']/label[last()]").click()

  20. time.sleep(4) # 网页返回数据需要时间

  21. self.html = self.driver.page_source

  22. def parser_data_for_url(self):

  23. '''从基金列表页获取每支基金的近一周收益和详情链接'''

  24. # 解析字符串格式的HTML文档对象,将传进去的字符串转变成_Element对象

  25. html = etree.HTML(self.html)

  26. tr_list = html.xpath("//table[@id ='dbtable']//tbody/tr")

  27. next_page = html.xpath("//div[@id ='pagebar']//label[last()]")

  28. for tr in tr_list:

  29. tds =tr.xpath("./td")

  30. # 将近一周收益和详情链接组成的元组加入fund_url_list列表

  31. self.fund_url_list.append((str(tds[8].text),str(tds[2].xpath("./a/@href")[0])))

  32. return next_page # 返回下一页

  33. #翻页控制器

  34. def over_page(self,next_page):

  35. # 获取最后一页

  36. kw = next_page[0].xpath("./label[contains(@class,'end')]")

  37. # print(kw)

  38. # 判断是否是最后一页,如果是,则返回False,否则返回True

  39. flag = True if len(kw)==0 else False

  40. return flag

  41. def get_every_fund_url(self, url, page):

  42. # page:要获取前多少页的基金数据

  43. # 1 发起请求

  44. # 2 获取数据,解析数据

  45. self.driver.get(url)

  46. self.html = self.driver.page_source

  47. # 当页数不为0且还有下一页时,执行下面的操作

  48. while page > 0 and self.next_page:

  49. next_page= self.parser_data_for_url()

  50. # 4 翻页继续爬取

  51. self.next_page = self.over_page(next_page)

  52. # 如果不是下一页,就继续翻页

  53. if self.next_page:

  54. self.parser_url()

  55. page -= 1

  56. # 返回每支基金近一周收益和详情链接

  57. return self.fund_url_list

  58. def close_driver(self):

  59. self.driver.quit()

  60. def save_data(data):

  61. wb = Workbook() # 新创建一个文件

  62. ws = wb.active # 获取当前正在运行的工作表/激活工作表

  63. #将数据一行一行插入到工作表中

  64. #列表第一个元素将作为标题

  65. for i in data:

  66. ws.append(i)

  67. wb.save("近6月基金排名_" + time.strftime('%Y%m%d%H%M%S')+".xlsx")

  68. # 多进程任务函数

  69. # 获取进入基金的详情页获取详细信息

  70. def run(url, nearly_1_week):

  71. driver = webdriver.PhantomJS()

  72. driver.get(url)

  73. page_html = etree.HTML(driver.page_source) # 获取页面源码

  74. #获取基金名称

  75. #通过xpath或者的是一个元素列表,要元素下面的子元素,需要取某个具体的元素,不能用列表取

  76. fund_name =page_html.xpath("//div[@class='fundDetail-tit']/div/text()")[0]

  77. #获取基金代码类名

  78. fund_code_class_name = page_html.xpath("//div[@class='fundDetail-tit']/div/span[last()]/@class")[0]

  79. #根据代码类名判断基金代码只有一个,还是有前后端两个

  80. if fund_code_class_name == "ui-num":

  81. fund_code = page_html.xpath("//div[@class='fundDetail-tit']/div/span[last()]/text()")[0]

  82. elif fund_code_class_name == "fundcodeInfo":

  83. fund_code_info = page_html.xpath("//div[@class='fundDetail-tit']/div/span[@class='fundcodeInfo']")[0]

  84. fund_code = "前端: " +fund_code_info.xpath("./span[1]/text()")[0] + " 后端: " + fund_code_info.xpath("./span[2]/text()")[0]

  85. #收益和净值所在的上层div

  86. data_of_fund = page_html.xpath("//div[@class='dataOfFund']")[0]

  87. #近1月

  88. nearly_1_month =data_of_fund.xpath("./dl[1]/dd[2]/span[last()]/text()")[0]

  89. #近1年

  90. nearly_1_year =data_of_fund.xpath("./dl[1]/dd[3]/span[last()]/text()")[0]

  91. #日期

  92. date = data_of_fund.xpath("./dl[2]/dt/p/text()")[0]

  93. date = re.findall(r"(\d{4}-\d{2}-\d{2})", date)[0] ifre.findall(r"(\d{4}-\d{2}-\d{2})", date) else ""

  94. #单位净值

  95. unit_net_worth =data_of_fund.xpath("./dl[2]/dd[1]/span[1]/text()")[0]

  96. #日增长率

  97. daily_growth_rate =data_of_fund.xpath("./dl[2]/dd[1]/span[2]/text()")[0]

  98. #近3月

  99. nearly_3_month =data_of_fund.xpath("./dl[2]/dd[2]/span[last()]/text()")[0]

  100. #近3年

  101. nearly_3_year =data_of_fund.xpath("./dl[2]/dd[3]/span[last()]/text()")[0]

  102. #累计净值

  103. accumulated_net =data_of_fund.xpath("./dl[3]/dd[1]/span[1]/text()")[0]

  104. #近6月

  105. nearly_6_month =data_of_fund.xpath("./dl[3]/dd[2]/span[last()]/text()")[0]

  106. #基金成立日

  107. since_established =data_of_fund.xpath("./dl[3]/dd[3]/span[last()]/text()")[0]

  108. #获取基金类型,风险程度,规模等信息所在的上层vid

  109. fund_info_item =page_html.xpath("//div[@class='infoOfFund']")[0]

  110. #获取基金的类型以及风险程度

  111. fund_type = fund_info_item.xpath(".//tr[1]/td[1]/a/text()")[0]

  112. fund_risk =fund_info_item.xpath(".//tr[1]/td[1]/text()")[1].split()[-1].strip()

  113. #获取基金规模

  114. fund_scale =fund_info_item.xpath(".//tr[1]/td[2]/text()")[0].split(":")[-1]

  115. #获取基金经理

  116. fund_manager =fund_info_item.xpath(".//tr[1]/td[3]/a/text()")[0]

  117. #获取基金成立日

  118. establishment_date =fund_info_item.xpath(".//tr[2]/td[1]/text()")[0].split(":")[-1]

  119. #获取管理人

  120. administrator =fund_info_item.xpath(".//tr[2]/td[2]/a/text()")[0]

  121. #获取评级类名

  122. fund_rating_class_name =fund_info_item.xpath(".//tr[2]/td[3]/div/@class")[0]

  123. data_list = []

  124. #将每支基金的详细信息拼接成一个列表,并返回

  125. data_list.append(str(fund_code))

  126. data_list.append(str(fund_name))

  127. data_list.append(str(date))

  128. data_list.append(str(unit_net_worth))

  129. data_list.append(str(accumulated_net))

  130. data_list.append(str(daily_growth_rate))

  131. data_list.append(str(nearly_1_week))

  132. data_list.append(str(nearly_1_month))

  133. data_list.append(str(nearly_3_month))

  134. data_list.append(str(nearly_6_month))

  135. data_list.append(str(nearly_1_year))

  136. data_list.append(str(nearly_3_year))

  137. data_list.append(str(since_established))

  138. #根据评级所在divid的类名判断当前基金是几星

  139. if fund_rating_class_name == 'jjpj1':

  140. data_list.append("一星")

  141. elif fund_rating_class_name == "jjpj2":

  142. data_list.append("二星")

  143. elif fund_rating_class_name == "jjpj3":

  144. data_list.append("三星")

  145. elif fund_rating_class_name == "jjpj4":

  146. data_list.append("四星")

  147. elif fund_rating_class_name == "jjpj5":

  148. data_list.append("五星")

  149. else:

  150. data_list.append("暂无评级")

  151. data_list.append(fund_type + " | " + fund_risk)

  152. data_list.append(str(fund_scale))

  153. data_list.append(str(fund_manager))

  154. data_list.append(str(establishment_date))

  155. data_list.append(str(administrator))

  156. driver.quit() # 关闭浏览器

  157. return data_list

  158. if __name__ == '__main__':

  159. start = time.time()

  160. #基金排行按近6月排行页面url

  161. url ="http://fund.eastmoney.com/data/fundranking.html#tall;c0;r;s6yzf;pn50;ddesc;qsd20200725;qed20210725;qdii;zq;gg;gzbd;gzfs;bbzt;sfbb"

  162. tiantian = Tiantian_spider() # 实例化Tiantian_spider类

  163. #获取每个基金的近1周收益和基金详情链接

  164. #传入参数为排行页面url和要获取数据的总页数

  165. url_list = tiantian.get_every_fund_url(url,4)

  166. #要获取的数据,也作为保存excel的标题

  167. data = [["基金代码", "基金简称", "日期", "单位净值", "累计净值", "日增长率", "近一周", "近1月", "近3月", "近6月", \

  168. "近1年", "近3年", "成立来", "基金评级", "基金类型", "基金规模", "基金经理", "成立日", "管理人"]]

  169. result = []

  170. #multiprocessing.cpu_count():获取cpu核数

  171. #新建一个进程池,最大放cpu核数个进程

  172. pool = multiprocessing.Pool(multiprocessing.cpu_count())

  173. for nearly_1_week, url in url_list:

  174. # pool.apply_async:异步执行,10个任务同时执行

  175. # 通过进程池来执行并发任务

  176. # 进程池会自动找不同个数的进程来执行任务函数run, 将args=(url, nearly_1_week)中的url, nearly_1_week两个参数传入run函数

  177. # .get()表示获取任务函数的返回值,即基金的详细信息

  178. result.append(pool.apply_async(func=run, args=(url,nearly_1_week)).get())

  179. pool.close() # 关闭进程池

  180. pool.join() # 阻塞进程,所有进程池中的任务都执行完毕了,才能继续执行主进程

  181. #将基金列表按基金的近6月收益率倒序排列后加入data

  182. data.extend(sorted(result, key=lambda x:x[9], reverse=True))

  183. save_data(data)

  184. end = time.time()

  185. print("耗时为:%s秒" % (end - start))

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

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/13155.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vm 虚拟机 Debian12 开启 root、ssh 登录功能

前言&#xff0c;安装的时候语言就选中文就好了。选择中文&#xff0c;在安装的时候就可以选择国内 163 的源。 开启 ssh 功能 先提权&#xff0c;用 root 账户 su安装 ssh 安装 ssh-server apt install openssh-server启动 ssh systemctl start ssh查看 ssh 状态 systemctl st…

u3d的ab文件注意事项

//----------------LoadAllAB.cs--------------------- using System.Collections;using UnityEngine;namespace System.IO{public class LoadAllAB : MonoBehaviour{ //读取本地string path "Assets/Actors/lznh/ab/animation/t_bl/";// Use this for initiali…

Keil手动安装编译器V5版本

V5编译器下载&#xff1a;免积分下载 新版的keil不会自动帮你安装V5版本的编译器&#xff0c;但是很多教程很多比赛所用单片机都是V5的编译器&#xff0c;所以用来开以前的或者开源的很多东西编译直接一大堆报错。 吐槽说完了接下来教你怎么解决 打开installer&#xff08;在…

搞大事!法国邀请芬兰公司建量子工厂

法国当地时间5月13日&#xff0c;法国总统马克龙宣布启动2024年度“选择法国”&#xff08;Choose France&#xff09;商业峰会。今年峰会召开前&#xff0c;法国赢得了创纪录的150亿欧元外国投资承诺&#xff0c;覆盖从人工智能到制药和能源等领域。 而涉及到量子领域最重磅的…

el-select下拉框 添加 el-checkbox 多选框,支持全选、取消全选

el-select下拉框 添加 el-checkbox 多选框&#xff0c;支持全选、取消全选 前言一、实现思路二、实现代码1.模板代码2. css 样式3.js 代码 DEMO 演示总结 前言 实现效果预览 提示&#xff1a;本内容基于element-ui 组件实现&#xff0c;如果使用其他组件库、可参考下面实现方…

关于GitHub仓库建立及提交问题

文章目录 前言GitHub仓库创建token令牌的获取GitHub克隆到本地GitHub上传文件 前言 为了整一个GitHub仓库然后上传文件&#xff0c;笔者看了不下100篇博客&#xff0c;20段教程&#xff0c;最后在两位大佬的帮助下&#xff0c;才整明白了&#x1f62d; 先提前说一嘴从 2021年8月…

网络爬虫安全:90后小伙,用软件非法搬运他人原创视频被判刑

目录 违法视频搬运软件是网络爬虫 如何发现偷盗视频的爬虫&#xff1f; 拦截违法网络爬虫 央视《今日说法》栏目近日报道了一名程序员开发非法视频搬运软件获利超700多万&#xff0c;最终获刑的案例。 国内某知名短视频平台报警称&#xff0c;有人在网络上售卖一款视频搬运…

刘邦的创业团队是沛县人,朱元璋的则是凤阳;要创业,一个县人才就够了

当人们回顾刘邦和朱元璋的创业经历时&#xff0c;总是会感慨他们起于微末&#xff0c;都创下了偌大王朝&#xff0c;成就无上荣誉。 尤其是我们查阅史书时&#xff0c;发现这二人的崛起班底都是各自的家乡人&#xff0c;例如刘邦的班底就是沛县人&#xff0c;朱元璋的班底是凤…

分布式搜索-elaticsearch基础 概念

什么是elaticsearch: 倒排索引&#xff1a;就是将要查询的内容分成一个个词条&#xff0c;在将词条文档id存入&#xff0c;词条是唯一的。 文档词条总结: mysql和Elasticsearch概念对比: 架构: 基本概念总结:

一线互联网大数据面试题核心知识库(100万字)

本面试宝典涵盖大数据面试高频的所有技术栈&#xff0c;包括Liunx&Shell基础&#xff0c;Hadoop&#xff0c;Zookpeer&#xff0c;Flume&#xff0c;Kafka&#xff0c;Hive&#xff0c;Datax&#xff0c;Maxwell&#xff0c;DolphinScheduler&#xff0c;Spark Core&SQ…

光伏行业该如何起步?

随着全球对可再生能源的需求日益增长&#xff0c;光伏行业作为其中的佼佼者&#xff0c;正迎来前所未有的发展机遇。然而&#xff0c;对于新进入者或希望在这一领域有所建树的企业来说&#xff0c;如何起步并稳健发展是一个值得深思的问题。以下是一些关于光伏行业起步的建议。…

微服务- protobuf 安装

这里写自定义目录标题 1&#xff1a;下载链接2 &#xff1a;下载对应的包3&#xff1a;解压到目录4&#xff1a;设置环境变量5: 查看版本 1&#xff1a;下载链接 https://github.com/protocolbuffers/protobuf/releases 2 &#xff1a;下载对应的包 3&#xff1a;解压到目录 4&…

从RTTR谈Reflection机制

虽然C11引入了RTTI、Metaprogramming 等技术&#xff0c;但C在Reflection编程方面依旧功能有限。在社区上&#xff0c;RTTR则提供了一套C编写的反射库&#xff0c;补充了C在Reflection方面的缺陷。 零、环境 操作系统Windows 11Visual StudioVisual Studio Community 2022 CMa…

2024.05.14 Diffusion 代码学习笔记

配环境 我个人用的是Geowizard的环境&#xff1a;https://github.com/fuxiao0719/GeoWizard。 出于方便考虑&#xff0c;用的pytorch官方的docker容器&#xff0c;因此python版本&#xff08;3.10&#xff09;和原作者&#xff08;3.9&#xff09;不同&#xff0c;其余都是一…

一文说通用户故事点数是什么?

一文说通用户故事点数是什么&#xff1f; 第26期&#xff1a;一文说通用户故事点数是什么&#xff1f; 用户故事点数是一种采用相对估算法进行估算的一种工具&#xff0c;一般采用斐波那契数列表征用户故事里说的大小&#xff0c;采用0 1 2 3 5 8 13这样的一些数字来表征用户…

【漏洞复现】Secnet-智能路由系统 actpt_5g.data信息泄露

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司(简称“安网通信”)的无线AP管理系统 0x02 漏洞描述 Secnet智能路由系统 acipt 5g.data 接口存在信息泄露漏洞&#xff0c;未经身份验证的远程攻击者可以利用此漏洞获取系统账户名密码等重要凭据&#xff…

全流程TOUGH系列软件实践技术应用

TOUGH系列软件是由美国劳伦斯伯克利实验室开发的&#xff0c;旨在解决非饱和带中地下水、热运移的通用模拟软件。和传统地下水模拟软件Feflow和Modflow不同&#xff0c;TOUGH系列软件采用模块化设计和有限积分差网格剖分方法&#xff0c;通过配合不同状态方程&#xff08;EOS模…

永磁同步电机的脉振高频注入无速度传感器simulink仿真模型

整理了永磁同步电机的脉振高频注入无速度传感器simulink仿真模型&#xff0c;该模型高频注入仿真pmsm&#xff0c;无感控制&#xff0c;解决0速转矩输出问题&#xff0c;插入式永磁同步电机&#xff0c;凸极&#xff0c;高频注入。MATLAB/simulink仿真&#xff0c;适合研究学习…

腾讯开源混元DiT文生图模型,消费级单卡可推理

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接…

【AI+漫画】程序员小李解决疑难杂症BUG的日常

周末花了点时间制作的AI漫画。 感慨一句&#xff0c;程序人生, 相伴随行。 原文链接&#xff1a;【AI漫画】程序员小李解决疑难杂症BUG的日常