实战+代码!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…

【Flutter 面试题】 如何让图片重复堆叠容器?

【Flutter 面试题】 如何让图片重复堆叠容器? 文章目录 写在前面口述回答补充说明写在前面 🙋 关于我 ,小雨青年 👉 CSDN博客专家,GitChat专栏作者,阿里云社区专家博主,51CTO专家博主。2023博客之星TOP153。 👏🏻 正在学 Flutter 的同学,你好! 😊 Flutter …

根据web访问日志,封禁请求量异常的IP,如IP在半小 时后恢复正常则解除封禁

在网络安全日益受到重视的今天&#xff0c;如何有效防范恶意流量和攻击成为了每个网站管理员必须面对的问题。恶意流量不仅会影响网站的正常运行&#xff0c;还可能导致服务器崩溃&#xff0c;给网站带来不可估量的损失。为了应对这一问题&#xff0c;我们特别推出了一款实用的…

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…

SQL注入之数据库基础

数据库基础 创建数据库 create 数据库名称;创建表 create table if not exists mobile(ID int(10) primary key auto_increment comment 手机编号 主键自增,Brand varchar(50) not null comment 手机品牌 非空约束,Model varchar(50) not null comment 手机型号 非空约束,Pr…

Keil手动安装编译器V5版本

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

vue使用postcss-pxtorem实现自适应

安装&#xff1a; npm install postcss-pxtorem -Dvue.config.js文件设置&#xff1a; css: {loaderOptions: {scss: {additionalData: import "~element-ui/packages/theme-chalk/src/common/var.scss";import"/styles/variables.scss";},postcss: {po…

OpenGL ES 面试高频知识点(二)

说说纹理常用的采样方式? 最邻近点采样(GL_NEAREST)和双线性采样(GL_LINEAR)。 GL_NEAREST 采样是 OpenGL 默认的纹理采样方式,OpenGL 会选择中心点最接近纹理坐标的那个像素,纹理放大的时候会有锯齿感或者颗粒感。 **GL_LINEAR 采样会基于纹理坐标附近的纹理像素,计…

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

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

python数据处理与分析入门-pandas使用(4)

往期文章&#xff1a; pandas使用1pandas使用2pandas使用3 pandas使用技巧 创建一个DF对象 # 首先创建一个时间序列 dates pd.date_range(20180101, periods6) print(dates)# 创建DataFrame对象&#xff0c;指定index和columns标签 df pd.DataFrame(np.random.randn(6,4), …

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

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

「AIGC算法」线性回归模型

线性回归是统计学和机器学习中一种常用的监督学习算法&#xff0c;用于预测连续数值型的输出。线性回归模型试图找到特征变量&#xff08;或称自变量&#xff09;与目标变量&#xff08;因变量&#xff09;之间的线性关系。 线性回归的两种主要类型&#xff1a; 简单线性回归&a…

学习Nginx(三):命令与信号

命令及选项 1. 显示帮助信息&#xff1a; [rootRockyLinux9 ~]# nginx -h nginx version: nginx/1.26.0 Usage: nginx [-?hvVtTq] [-s signal] [-p prefix][-e filename] [-c filename] [-g directives]选项:-?,-h : 显示帮助信息-v : 显示版本信息-V …

Error in debuggerConnector: connect ECONNREFUSED问题解决

最近重新开始electron开发&#xff0c;两三年前写的代码几乎看不懂了。。然后debug一下&#xff0c;直接报错了&#xff1a; Debugger listening on ws://127.0.0.1:20793/d146ffdb-c3b8-4480-a8d8-d04bb643c7c1 For help, see: https://nodejs.org/en/docs/inspector Error i…

关于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;朱元璋的班底是凤…

大模型技术介绍和实现流程以及向量库的介绍

多模态大模型&#xff1a;&#xff08;Multimodal Models&#xff09;指能够处理和生成多种类型数据&#xff08;如文本、图像、音频等&#xff09;的机器学习模型。该模型整合了来自不同模态的数据&#xff0c;从而提高了任务执行的准确性和广度。 一、多模态大模型 任务步骤…

分布式搜索-elaticsearch基础 概念

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

Linux上执行内存中的脚本和程序

在Linux中可以不需要有脚本或者二进制程序的文件在文件系统上实际存在&#xff0c;只需要有对应的数据在内存中&#xff0c;就有办法执行这些脚本和程序。 原理其实很简单&#xff0c;Linux里有办法把某块内存映射成文件描述符&#xff0c;对于每一个文件描述符&#xff0c;Lin…