爬虫方式(模拟用户)

基于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 类和属性的表格元素
posted @ 2024-05-23 18:08  卓亦苇  阅读(34)  评论(0编辑  收藏  举报