首页 > 其他分享 >爬虫方式(模拟用户)

爬虫方式(模拟用户)

时间:2024-05-23 18:21:32浏览次数:16  
标签:WebDriver Selenium driver 爬虫 用户 select table csv 模拟

基于rake的爬取代码

require 'nokogiri'
require 'json'
require 'open-uri'
namespace :spider_sbi_code_info do
  task table_data: :environment do
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('--headless') # 无头模式,不显示浏览器界面
    driver = Selenium::WebDriver.for :chrome, options: options
    csv_filename_list = ["table_data_0_普通株式.csv", "table_data_1_米国ETF.csv", "table_data_2_各国ADR.csv"]
    begin
      # 初始化文件
      csv_filename_list.each do |file|
        if File.exist?("db/csv/#{file}")
          File.delete("db/csv/#{file}")
          p "删除已存在的文件 #{file}"
        end
      end
      # 访问目标网站
      url = 'https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_usequity_list.html'
      driver.get(url)
      dropdowns = driver.find_elements(css: '.form-control.input-sm')

      # 遍历每个下拉列表并选择选项为 "-1"
      dropdowns.each do |dropdown|
        if dropdown.tag_name == 'select'
          # 初始化 Select 对象
          select = Selenium::WebDriver::Support::Select.new(dropdown)

          # 通过 value 属性选择选项为 "-1"
          select.select_by(:value, '-1')
        end
      end

      # 等待页面加载完全
      wait = Selenium::WebDriver::Wait.new(timeout: 10)
      wait.until { driver.execute_script('return document.readyState') == 'complete' }

      # 获取页面内容
      html_content = driver.page_source

      doc = Nokogiri::HTML(html_content)
      tables = doc.css('.foo_table, div.accTbl01 > table[summary="layout"]')

      if tables.any?
        # 提取表格数据并写入 CSV 文件
        tables.each_with_index do |table, index|
          # 提取表格数据
          table_data = table.css('tr').reject do |row|
            index > 2 && row.css('th, td').map(&:text) == ["ティッカー", "銘柄(英語)", "事業内容", "市場"]
          end.map { |row| row.css('th, td').map { |cell| cell.text.gsub("\n", '') } }

          # 确定 CSV 文件名
          csv_filename = if index > 2
                           "db/csv/#{csv_filename_list.last}"
                         else
                           "db/csv/#{csv_filename_list[index]}"
                         end

          # 写入 CSV 文件
          CSV.open(csv_filename, 'a') do |csv|
            table_data.each { |row| csv << row }
          end

          p "存入数据到 #{csv_filename}"
        end

      else
        p "没有找到表格"
      end

      title = "SBI証券取扱銘柄リスト一覧の送付_#{Date.today.strftime('%Y/%m/%d')}"
      content = "関係者各位<br>お疲れ様です。<br>SBI証券のサイトより、取扱銘柄一覧をスクレイピングしましたので、<br>メールにて送付させて頂きました。<br>スクレイピング先のURL:<br>https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_usequity_list.html<br><br>ご確認をお願い致します。"
      attachments = csv_filename_list.map { |filename| File.join('db/csv', filename) }
      ExtMail.send_mail(title: title, body: content, template_name: 'system_mail', attachments: attachments, to: Yml::MAIL[:spider_sbi_stocks][Rails.env])

      csv_filename_list.each do |file|
        if File.exist?("db/csv/#{file}")
          File.delete("db/csv/#{file}")
          p "删除已存在的文件 #{file}"
        end
      end
    rescue Exception => e
      p "发生错误: #{e.message}"
    ensure
      driver.quit if driver
    end
  end
end
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument('--headless') # 无头模式,不显示浏览器界面
  driver = Selenium::WebDriver.for :chrome, options: options

配置并启动 Selenium WebDriver:

  • Selenium::WebDriver::Chrome::Options.new 创建一个 Chrome 浏览器的选项实例。
  • options.add_argument('--headless') 添加一个选项,使浏览器以无头模式运行(不显示界面)。
  • Selenium::WebDriver.for :chrome, options: options 启动 Chrome 浏览器并应用这些选项。
dropdowns = driver.find_elements(css: '.form-control.input-sm')

找到页面上的所有下拉列表元素:

  • driver.find_elements(css: '.form-control.input-sm') 使用 CSS 选择器找到页面上所有具有 form-control input-sm 类的元素。
dropdowns.each do |dropdown|
        if dropdown.tag_name == 'select'
          select = Selenium::WebDriver::Support::Select.new(dropdown)
          select.select_by(:value, '-1')
        end
      end

遍历每个找到的下拉列表,并选择值为 -1 的选项:

  • dropdowns.each do |dropdown| 迭代每个下拉列表。
  • if dropdown.tag_name == 'select' 检查元素是否是 select 标签。
  • select = Selenium::WebDriver::Support::Select.new(dropdown) 创建一个新的 Select 对象。
  • select.select_by(:value, '-1') 通过 value 属性选择值为 -1 的选项。
wait = Selenium::WebDriver::Wait.new(timeout: 10)
wait.until { driver.execute_script('return document.readyState') == 'complete' }

等待页面完全加载:

  • wait = Selenium::WebDriver::Wait.new(timeout: 10) 创建一个新的 Wait 对象,设置超时时间为 10 秒。
  • wait.until { driver.execute_script('return document.readyState') == 'complete' } 等待页面的 readyState 变为 complete,表示页面加载完成。
html_content = driver.page_source
doc = Nokogiri::HTML(html_content)

这段代码获取页面内容并使用 Nokogiri 解析:

  • html_content = driver.page_source 获取当前页面的 HTML 源代码。
  • doc = Nokogiri::HTML(html_content) 使用 Nokogiri 解析 HTML 内容,创建一个文档对象。
tables = doc.css('.foo_table, div.accTbl01 > table[summary="layout"]')

这行代码使用 CSS 选择器找到页面上的特定表格:

  • tables = doc.css('.foo_table, div.accTbl01 > table[summary="layout"]') 找到具有特定 CSS 类和属性的表格元素

标签:WebDriver,Selenium,driver,爬虫,用户,select,table,csv,模拟
From: https://www.cnblogs.com/zhuoblog/p/18209116

相关文章

  • 配电网 馈线 台区 用户
    所谓分域,是根据配电网电压等级和电网公司运营管理特点,将终端层划分为线路域、台区域和用户域3个信息域。其中,线路域以单条馈线为单位,覆盖从变电站出线侧至10/0.4kV配电变压器的馈线线路,通常在变电站、开闭站、环网柜、配电室等位置部署量测点。台区域以单个10/0.4kV......
  • NFLS NOI模拟 序列
    涉及知识点:分治、贪心前言没错……又是一道叫序列的题……题意有一个长为\(n\(\leq10^5)\)的序列\(a\),你可以花费\(x^2\)的代价将\(a_i\)变成\(a_i+x\),使得代价加上\(a\)两两数之差的绝对值乘以一个给定常数\(c\)的总和最小。思路拿到手觉得是一个贪心,但是直接......
  • C#应用的用户配置窗体方案 - 开源研究系列文章
          这次继续整理以前的代码。本着软件模块化的原理,这次笔者对软件中的用户配置窗体进行剥离出来,单独的放在一个Dll类库里进行操作,这样在其它应用程序里也能够快速的复用该类库,达到了快速开发软件的效果。      笔者其它模块化应用的例子:      C#的关于......
  • NFLS NOI模拟 树数术
    涉及知识点:树、倍增、单调栈题意给你一颗有\(n\(\leq7\times10^5)\)个节点的树,再给你一个长为\(m\(\leq7\times10^5)\)的序列,序列中的值代表树上点的编号,有\(q\)次询问,每次询问取原序列的\(k\(\sumk\leq7\times10^5)\)个子区间并连起来成为一段新的序列,问新的序列......
  • linux核心基础-用户管理
    一、linux用户管理前言1、linux用户信息配置文件/etc/passwd2、/etc/passwd字段信息解释3、其余用户,组相关配置文件/etc/passwd用户信息/etc/shadow用户密码信息/etc/group用户组信息/etc/gshadow用户组密码信息,在大公司,用户和组数量很大的情况下,需要制定复杂的......
  • 栈模拟
    洛谷P4387验证栈序列#include<bits/stdc++.h>usingnamespacestd;intmain(){intq;cin>>q;for(inti=0;i<q;i++){intn,x;cin>>n;stack<int>pushed;vector<int>a,b;for(......
  • 4/7一文讲透网络传输流程 epoll内核模型 reactor用户空间处理模型
    epoll是内核如何将由层层协议栈去除tcp头,根据四元组查socket文件,将sk_buffer放到socket接受队列的 reactor  五种IO模型,三种线程处理模型     回溯算法之全排列 将所有需要用到的数组包括路径数组状态数组都初始化好然后都放进dfs参数里面 这......
  • 模拟redis的setIfAbsent
    一、导入依赖<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.6.2</version></dependency> 二、缓存类publicclassCustomCache<K,V>{private......
  • 【EasyClick】MacOS连接MuMu模拟器
    一、打开模拟器,IDE中操作:设备连接-USB连接 二、提示 未发现任何设备,打开运行日志查看 三、命令行启动,进入adb目录下启动服务 四、重新操作第一步,连接成功! ......
  • 进程通信--内存映射区(用户区)
    在进程间通信(IPC)中,内存映射区(Memory-MappedArea或Memory-MappedFile)是一种高效的通信机制,通过共享内存实现进程间的数据交换。使用内存映射区的主要优点是,它允许不同进程访问同一个物理内存区域,而不需要显式的数据拷贝。内存映射区的概念内存映射区是将文件或设备的内容映射......