爬取东方财富股票信息

news2024/11/24 2:27:20

爬取股票信息

爬虫爬取信息,一般有两种大的思路,分别是:

  • 模拟header信息,发送请求,得到相应的数据(html文件 或者 json数据)
  • 使用selenium模拟打开浏览器,然后利用selenium提供的函数抓取网页中标签信息,从而获取到页面上的数据

本文基于第二种,即selenium,爬取东方财富的股票数据。

目标网址:http://quote.eastmoney.com/center/gridlist.html#hs_a_board

目标数据:网页table标签中的股票信息

基础版-获取到一页股票数据

思路:

  • 利用selenium加载网页
  • 利用beautiful soup解析网页内容
  • 利用beautiful soup,根据类名或者标签,找到存储股票信息的tbody
  • 根据tr标签,找到所有的tr,一个tr代表一行数据(一只股票)
  • 遍历所有的tr,并提取该行中所需要的信息,输出结果

代码如下:

from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.service import Service
#webdriver的路径
gecko_driver_path = 'geckodriver.exe'
#固定搭配直接用就行了
service = Service(executable_path=gecko_driver_path)
# 创建Chrome浏览器驱动对象
driver = webdriver.Firefox(service=service)

# driver = webdriver.Chrome(service = service)
# driver = webdriver.Firefox()
# 构建URL
url = "http://quote.eastmoney.com/center/gridlist.html#hs_a_board"
# 发起GET请求
driver.get(url)
# 等待页面加载完成
driver.implicitly_wait(10)
# page_source,就是html文本内容
page_source = driver.page_source
# print(page_source)
# 利用BeautifulSoup解析响应内容,转化为BeautifulSoup格式,方便进一步处理
soup = BeautifulSoup(page_source, "html.parser")
# print(soup)
# 分析发现:soup和page_source内容上并没有什么不同,只是soup更为精简了,去除了很多空格
# 选取代表股票信息的table节点,返回的是一个list,代表找到的所有符合条件的tbody
res = soup.select(".table_wrapper-table tbody")
print(res)
# 经分析,发现只有一个tbody,直接取之就可
tbody = res[0]
print(tbody)
# 获取所有的行,通过寻找tr节点,返回一个list
all_rows = tbody.find_all("tr")
print(len(all_rows))

# 遍历每行数据
for row in all_rows:
    # 找到本行,所有的td,即所有的列数据
    columns = row.find_all("td")
    # print(columns)
    # 提取所需的股票信息,通过.text获取节点/标签的内容
    # 序号
    id = columns[0].text
    # 股票代码
    share_code = columns[1].text
    # 股票名称
    stock_name = columns[2].text
    # 最新价
    new_price = columns[4].text
    # 涨跌幅
    change_percent = columns[5].text
    # 涨跌额
    change_price= columns[6].text
    print(id,share_code,stock_name,new_price,change_percent,change_price)

# 关闭浏览器
driver.quit()

截图如下:

在这里插入图片描述

升级版-翻页获取所有数据并存为csv

思路:

  • 模拟点击翻页
  • 每读取一行数据,就将数据存到csv文件

代码如下:

import csv
import time

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.service import Service

# 1、firefox浏览器配置
# 设置驱动路径
# gecko_driver_path = 'geckodriver.exe'
# service = Service(executable_path=gecko_driver_path)
# 创建Chrome浏览器驱动对象
# driver = webdriver.Firefox(service=service,options=options)

# 2、chrome浏览器配置
# 配置一些选项
chrome_driver_path = 'chromedriver.exe'
service = Service(executable_path=chrome_driver_path)
options = Options()
# 不打开浏览器,提升效率
options.add_argument("--headless")
# 禁用GPU加速,提升效率
options.add_argument("--disable-gpu")
# 创建Chrome浏览器驱动对象
driver = webdriver.Firefox(service=service,options=options)

# 构建URL
url = "http://quote.eastmoney.com/center/gridlist.html#hs_a_board"

# 发起GET请求
driver.get(url)

# 等待页面加载完成
# 显式等待,最长等待10秒
wait = WebDriverWait(driver, 10)
# 直到表格元素可见
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".table_wrapper-table")))

# 创建CSV文件
csv_file = open("股票数据.csv", "w", newline="", encoding="utf-8-sig")
writer = csv.writer(csv_file)
# 写入表头信息
writer.writerow([
    '序号','股票代码','股票名称','最新价格','涨跌幅','涨跌额'
])
page_count = 0
while True:
    # 强制等待:每次等待0.5秒再执行
    time.sleep(0.5)
    # 解析响应内容
    soup = BeautifulSoup(driver.page_source, "html.parser")
    # 获取股票信息表格
    res = soup.select(".table_wrapper-table tbody")
    tbody = res[0]
    all_rows = tbody.find_all("tr")
    # 遍历当前页面所有数据
    for row in all_rows:
        # 获取每列数据
        columns = row.find_all("td")
        # 提取所需的股票信息
        # 序号
        id = columns[0].text
        # 股票代码
        share_code = columns[1].text
        # 股票名称
        stock_name = columns[2].text
        # 最新价
        new_price = columns[4].text
        # 涨跌幅
        change_percent = columns[5].text
        # 涨跌额
        change_price = columns[6].text

        # 写入 一行数据 至CSV文件
        writer.writerow([
            id,share_code,stock_name,new_price,change_percent,change_price
        ])

    page_count += 1
    print('写入第', page_count, '页')
    # 查找下一页按钮
    # 标签类名 class ="next paginate_button"
    next_page_button = driver.find_element(By.CSS_SELECTOR, ".paginate_button.next")
    print(next_page_button.text)
    # 判断下一页按钮是否可点击,如果不可点击,则表示已经是最后一页
    if "disabled" in next_page_button.get_attribute("class"):
        break

    # 点击下一页按钮
    next_page_button.click()

    # 等待页面加载完成
    # 直到表格元素可见
    wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".table_wrapper-table")))

# 关闭CSV文件
csv_file.close()
# 关闭浏览器
driver.quit()

代码中的技术点:

  • 设置options,禁止GPU渲染
  • 设置options,禁止打开浏览器
  • 设置selenium时间等待策略,防止潜在的由于元素未加载完成而导致的错误

遇到的问题

问题1:缺乏驱动报错

selenium.common.exceptions.NoSuchDriverException: Message: Unable to obtain driver for chrome using Selenium Manager.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location

网络上有多种解决方案:

**方案1:**经过研究发现,下载相应版本的浏览器、浏览器驱动,然后将驱动与python程序同文件夹下,但是并不能解决问题,还是找不到驱动。虽然无法解解决问题,但是下载相应驱动肯定是必须的一个环节。

在python中使用selenium的话,首先需要下载浏览器以及浏览器驱动,相应的资源链接如下:

  • 火狐的各历史版本:Firefox各历史版本链接
  • 火狐各驱动历史版本:Firefox_selenium驱动各版本
  • chrome驱动的各历史版本:Chrome各历史版本
  • chrome浏览器的历史版本:谷歌浏览器历史版本
  • chrome驱动:https://chromedriver.chromium.org/downloads
  • chrome以及驱动的 最新版本、测试版本等:https://googlechromelabs.github.io/chrome-for-testing/

备注:需要注意,驱动与浏览器需要互相匹配,前四个链接存在版本不全的问题,chrome最新版本可以从最下边的链接下载。

**方案2:**同时发现有其他博主遇到类似的问题,同样的代码,python310不行,311却可以。

其解决方法是,修改模块的源代码,具体见如下链接:

https://blog.csdn.net/qq_63401240/article/details/132406123

不过经过实践,注释掉模块中的相关代码也还是报错,依然找不到驱动。

**方案3:**有网友提出,直接指定驱动地址,最终经过验证,解决了”找不到驱动“的问题

from selenium.webdriver.chrome.service import Service

gecko_driver_path = 'C:\All\software\Anaconda\geckodriver.exe'
service = Service(executable_path=gecko_driver_path)
driver = webdriver.Firefox(service=service)

参考链接为:

https://blog.csdn.net/CcReborn/article/details/132656781

问题2:爬取过程总是中断

描述:使用不打开浏览器的方式爬取数据,爬着爬着,就会报错,每次到达的页面都不一样,每次报错的代码也不一样

分析:大概率是由于某些元素未加载完成导致的,且与电脑的网络状态存在一定关联

解决:

在每次执行相关操作前,添加等待策略,包括强制等待、隐式等待、显式等待等,发现隐式等待、显式等待不太奏效。

强制等待,每次操作之前都设置time.sleep(),最终爬取过程很顺利,没有再遇到问题。

总体来讲,遇到元素未加载完成导致的错误,可以考虑三种策略结合使用。sleep作用最强,但是有时候也最耗时。

问题3:数据重复写入

描述:有几行数据被写入两次

分析:写入CSV文件时,数据出现冲突

解决:可以考虑先把所有数据存到变量里边,最后统一写入文件(仅限于数据量比较小,不会使内存爆炸的情况)。不过该问题属于小问题,并没有去解决。

在这里插入图片描述

问题4:禁止GPU加速、禁止打开浏览器,仅chrome支持

描述:相关的option配置不支持firefox,暂时没有研究原因。有可能只是针对chrome的特色功能。

补充:selenium等待策略

Selenium中常用的等待时间方式有三种:

  • 强制等待:time.sleep()
  • 隐式等待:implicitly_wait()
  • 显式等待:WebDriverWait()

强制等待

设置等待最简单的方法就是强制等待,其实就是time.sleep()方法。不管它什么情况,让程序暂停运行一定时间,时间过后继续运行。

优点:简单暴力,可以解决大多数错误。

缺点:不智能。如果设置的时间太短,元素还没有加载出来一样会报错。设置的时间太长,则会浪费时间。

隐式等待

WebDriver提供了mplicitly_wait()方法来实现隐式等待。隐式等待相当于设置全局等待,在定位元素时,对所有元素设置的超时时间。implicitly_wait()默认参数的单位为秒,默认设置超时时间为0,设置后这个隐式等待会在WebDriver对象实例的整个生命周期起作用。

优点:可以解决大部分错误

缺点:实际应用场景中,driver(浏览器)要等待的元素和脚本要操作的元素未必相同,也就是说,脚本要操作的元素已经出现,但因为设置了全局等待,driver(浏览器)也会继续等待页面上其他无关元素,直至整个页面加载完毕。所以与显式等待相比,可能会出现一些无效等待的情况。

示例:

# 等待页面加载完成,隐式等待,最长等待10秒
driver.implicitly_wait(10)

显式等待

显示等待是一种更智能的等待方式。显示等待比隐式等待更节省测试时间,个人更推荐使用显示等待的方式来判断页面元素是否出现。程序会每隔一段时间(默认为0.5秒,可自定义)执行一下判断条件,等待某个条件成立时继续执行,否则在达到最大时长抛出超时异常。

优点:智能化、节约时间

缺点:个别场景貌似无法解决问题(个别场景:比如上百页的数据需要去爬取、去点击,但是不绝对)

示例:

# 等待页面加载完成
# 显式等待,最长等待10秒
wait = WebDriverWait(driver, 10)
# 直到表格元素可见
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".table_wrapper-table")))

等待策略参考链接:

https://www.cnblogs.com/wuzm/p/12421811.html

https://zhuanlan.zhihu.com/p/581883844

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

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

相关文章

高防CDN:企业网络安全的坚强后盾

随着互联网的快速发展,企业的网络面临着越来越多的安全威胁。在这种背景下,高防CDN(Content Delivery Network)已经成为了企业网络安全的坚强后盾。本文将理性分析高防CDN对于企业发展的影响,强调其在维护网络稳定性、…

内核态内存映射

内核态的内存映射机制,主要包含以下几个部分: 内核态内存映射函数 vmalloc、kmap_atomic 是如何工作的;内核态页表是放在哪里的,如何工作的?swapper_pg_dir 是怎么回事;出现了内核态缺页异常应该怎么办&am…

MySQL(10):创建和管理表

基础知识 在 MySQL 中,一个完整的数据存储过程总共有 4 步,分别是:创建数据库、确认字段、创建数据表、插入数据。 要先创建一个数据库,而不是直接创建数据表:从系统架构的层次上看,MySQL 数据库系统从大到…

Android 10.0 SystemUI启动流程

1、手机开机后,Android系统首先会创建一个Zygote(核心进程)。 2、由Zygote启动SystemServer。 3、SystemServer会启动系统运行所需的众多核心服务和普通服务、以及一些应用及数据。例如:SystemUI 启动就是从 SystemServer 里启动的…

浅谈前端自定义VectorGrid矢量瓦片样式

目录 前言 一、VectorGrid相关API介绍 1、VectorGrid 2、 LayerStyles样式详解 二、样式自动配置 1、页面定义 2、地图及PBF瓦片引入 3、矢量瓦片样式定义 4、鼠标事件交互 三、最终效果 1、自定义样式展示 2、鼠标交互 总结 前言 在上一篇博客中,详细讲…

`rest-client`库

rest-client是一个在Ruby编程语言中用于发送HTTP请求的库。它提供了简单且易于使用的接口,用于发送GET、POST、PUT、DELETE等各种类型的HTTP请求,并处理响应。 以下是rest-client库的一些常见用法示例: 发送GET请求: require ‘…

《算法通关村—轻松搞定合并二叉树》

《算法通关村—轻松搞定合并二叉树》 描述 leetcode 617 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵…

【网络知识必知必会】聊聊数据链路层以太网

文章目录 前言1. 认识以太网2. 以太网帧格式已经有了ip地址, 为什么还要有 mac 地址呢?认识MTUMTU对IP协议的影响MTU对UDP协议的影响MTU对于TCP协议的影响 总结 前言 本文继续来聊聊网络传输中数据链路层中的一个代表协议, 以太网. 以太这个词其实最早出现在物理学当中, 在早…

前端工程化(vue2)

一、环境准备 1.依赖环境:NodeJS 官网:Node.js 2.脚手架:Vue-cli 参考网址:安装 | Vue CLI 介绍:Vue-cli用于快速的生成一个Vue的项目模板。主要功能有:统一的目录结构,本地调试&#xff0…

麒麟系统查看磁盘UUID方法

通过查看 /dev/disk/by-uuid/ 目录下的软连接确定磁盘UUID ls -l /dev/disk/by-uuid/ 命令输出入下图所示,红框中即为磁盘UUID号 通过 blkid 命令查看系统中某块磁盘的uuid 号 blkid 命令输出如下图所示,UUID”” 中即为磁盘UUID号 开机自动…

五:ffmpe主要参数的使用

目录 一:回顾一下主要参数 二:使用主要参数操作视频 1、-i 输入流的使用 2、-i 配合 输出流-f使用 三、使用-ss开始时间进行转换 四、使用-t参数,设置转换的时长 一:回顾一下主要参数 -i 设定输入流。 支持本地和网络流 -f …

数学到底在哪里支撑着编程?

如果编程语言是血肉,那么数学的思想和知识就是灵魂。它可以帮助你选择合适的数据结构和算法,提升系统效率,并且赋予机器智慧。在大数据和智能化的时代更是如此。举个例子,我们在小学就学过的余数,其实在编程的世界里也…

3D 线激光相机的激光条纹中心提取方法

论文地址:Excellent-Paper-For-Daily-Reading/application/centerline at main 类别:应用——中心线 时间:2023/11/06 摘要 线激光条纹中心提取是实现线激光相机三维扫描的关键,根据激光三角测量法研制了线激光相机,基于传统 Steger 法对其进行优化并提出一种适用于提…

淘宝店铺所有商品数据接口(taobao.item_search_shop)

淘宝店铺所有商品数据接口可以使用淘宝开放平台提供的API接口获取。要使用这个接口,需要在淘宝开放平台上注册账号并申请App Key和App Secret,获取API访问权限。 使用淘宝店铺所有商品数据接口时,需要传入shop id参数来获取相应的商品信息。…

【Redis】掌握篇--Redis与SSM进行整合

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于Redis的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一.Redis与SSM的整合 1.添加Redis依赖 2…

「随笔」浅谈2023年云计算的发展趋势

在2023年,云计算的发展趋势将受到政治、经济、社会和科技四个维度的影响。以下是对这些维度的具体分析: 1.1 政治维度: 全球政策推动: 随着全球各国政策对云计算的重视程度不断提高,云计算服务将获得更广泛的市场准入…

安科瑞关于新能源电动汽车有序充电的对策-安科瑞黄安南

摘要 随着我国能源战略发展以及低碳行动的实施,电动汽车已逐步广泛应用,而电动汽车的应用非常符合当今社会对环保意识的要求,以及有效节省化石燃料的消耗。由于其没有污染排放的优点以及政府部门的关注,电动汽车将成为以后出行的…

后端工程化 | SpringBoot 知识点

文章目录 [SpringBoot] 后端工程化1 需求2 开发流程3 RequestController 类(操作类)3.1 简单参数(形参名和请求参数名一致)3.2 简单参数(形参名和请求参数名不一致)3.3 复杂实体参数3.4 数组参数3.5 集合参…

10 特征向量与特征值

特征向量与特征值 什么是特征向量三维空间的旋转矩阵和线性变换特征向量二维线性变换不一定有特征向量一个特征值可能不止一个特征向量特征基 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 图1 预备知识 什么是特征向量 图1 特征向量 线性变换过程中&#xff…

测试常见异常总结

为了更好地保障测试质量,除了测试正向场景,也需要验证软件在异常情况下的行为和反应。本文分享一些测试过程中常见的异常。 通过模拟和触发各种异常情况,测试人员可以验证软件对异常的处理是否符合预期,是否能够正确地处理和恢复。…