Ruby의 웹 캡처를 사용하여 학교 양식 자동화

16546 단어 rubywebdevbeginners
나의 친한 친구이자 전 동료인 예첼은 최근 루비로 구글 폼을 자동으로 제출하는 것에 관한 글을 썼다.그와 나는 자동화 방면에서 같은 목적을 가지고 있다. 그것은 바쁜 월급쟁이 가정을 위해 귀중한 시간을 절약하고 그들을 위해 매일 아침 준비를 하는 것이다. 그러나 우리 학교는 매우 다른 시스템을 사용하여 그들의 매일 관상바이러스 건강 수요를 만족시켰다.
Google 양식을 자동으로 제출하는 방법을 배우고 싶으면 Yechiel의 멋진 게시물을 찾아보세요.


이 글에서 나는 내가 어떻게 우리 학교 시스템을 위해 제출 과정을 자동화하고 이 시스템은 사용자 정의 사이트를 사용하는지 공유할 것이다.
tl;dr 이 프로그램의 코드와 어떻게 사용하는지 GitHub 에서 찾을 수 있습니다.
매일 학교 양식을 성공적으로 제출하기 위해서는 다음과 같은 응용 프로그램이 필요합니다.
  • 내 사용자 이름과 비밀번호
  • 로 사이트에 로그인
  • HTML 확인란 두 개 선택
  • HTML5 캔버스 요소에 그리기
  • 제출 버튼 누르기
  • 내 목록에 있는 모든 아이를 설명하고 모든 아이에게 동작을 반복한다
  • 아이의 양식이 제출된 경우 목록에 있는 아이를 건너뛰기
  • 제출에 성공하면 피드백을 주거나 문제가 발생했는지 알려주십시오
  • 이것은 모든 아이들의 표의 외관이다.

    이 문제를 해결하기 위해 저는 Watir를 사용했습니다. 이것은 루비gem입니다. 당신의 응용 프로그램이 웹 브라우저와 상호작용을 할 수 있도록 합니다. 마치 사람들이 브라우저와 상호작용을 하는 것과 같습니다.Watir를 사용하면 링크를 클릭하거나 양식을 작성하거나 양식을 제출할 수 있습니다.
    Gemfile 에 다음 세 개의 gem을 추가했습니다. 응용 프로그램 의존 항목을 나열할 수 있습니다.
    gem 'dotenv'
    gem 'watir'
    gem 'webdrivers'
    
    응용 프로그램의 환경 변수를 관리하는 데 dotenvgem를 사용합니다.구체적으로, 나는 어떤 공공 버전 제어에도 나의 사용자 이름과 비밀번호를 저장하지 않기 위해 환경 변수를 사용하고 응용 프로그램의 변수에 접근한다.
    또한 webdriversgem는 Chrome Webdriver를 사용할 수 있도록 하고 크롬 브라우저에서 웹 사이트를 방문하는 것을 시뮬레이션합니다.
    일단 내가 의존항이 생기면, 나는 나의 응용 프로그램을 구축할 준비가 되어 있다.나는 가능한 한 적은 방법으로 나의 코드를 봉인하는 것을 좋아한다.그것은 나로 하여금 문제가 발생했을 때 진단을 더욱 쉽게 하게 했다.
    내가 구축한 첫 번째 방법은 #call 응용 프로그램의 입구점이다.이 방법은 다음 방법#get_sign_in_page을 호출합니다. 이 방법은 첫 번째 단추에 Watir 실례와 cicks를 실례화합니다. 이 단추를 눌러야 로그인 페이지에 들어갈 수 있습니다.
    def call(url)
      get_sign_in_page(url)
    end
    
    def get_sign_in_page(url)
      browser = Watir::Browser.new :chrome, headless: false
      browser.goto(url)
    
      click_first_sign_in(browser)
    end
    
    그리고 위의 두 번째 방법 호출 #click_first_sign_in 은 호출 방식에 따라 실행됩니다. 첫 번째 로그인 링크를 누르십시오.
    def click_first_sign_in(page)
      page.link(:class => [
        'text-bold',
        'color-white',
        'edu-connect',
        'btn',
        'color-blue',
        'border-blue',
        'btn-connect-briut'
        ]).click
    
      fill_in_sign_in_form(page)
    end
    
    CSS 클래스의 집합을 사용하여 로그인 링크를 찾아서 Watir에 문자열 그룹으로 전달하는 실례 방법 #link 을 사용합니다.일단 내가 정확한 버튼을 확정한 후에 나는 #click 방법으로 그것을 클릭한다!너는 방법의 이름이 이렇게 좋은 것을 좋아하지 않니?
    이 메서드는 다음 메서드#fill_in_sign_in_form를 호출하여 로그온 프로세스를 완료합니다.
    def fill_in_sign_in_form(page)
      page.text_field(id: /HIN_USERID/).set(ENV['USERNAME'])
      page.text_field(id: /Ecom_Password/).set(ENV['PASSWORD'])
      page.button(name: /loginButton2/).click
    
      fill_out_declaration(page)
    end
    
    위의 방법은 폼에서 사용자 이름과 비밀번호의 텍스트 필드를 찾고 환경 변수를 값으로 제공합니다.그런 다음 제출 버튼을 찾아 클릭합니다.마지막으로, 나는 이어서 다음 방법을 토론했다. 그것은 내 아이의 건강 표를 돌보는 것이다.
    다음 방법에서는 먼저 CSS 클래스를 사용하여 하위 객체 목록<div>을 찾습니다.그리고 나는 그 중의 링크 목록을 두루 훑어보았다<div>.
    교체 과정 중, 나는 모든 원소 (즉 모든 하위 원소) 의 표가 이미 제출되었는지 검사한다.만약 있다면, 나는 컨트롤러에 이 점을 설명하기 위해 짧은 메시지를 출력할 것이다.만약 없다면, 나는 #click 아이와 #complete_individual_form:
    def fill_out_declaration(page)
      kids_list = page.div(class: /name_student_infile/)
      kids_list.links.each do |kid|
        if check_already_submitted?(page)
          puts "Form already submited"
          next
        end
        kid.click
        complete_individual_form(page)
      end
    end
    
    단일 폼을 처리하여 그 요구를 만족시키다.이것은 두 개의 체크 상자 중 하나를 클릭하고 프로그램이 캔버스 요소에 점을 그립니다.
    def complete_individual_form(page)
      # two checkboxes
      page.label(:xpath => '/html/body/div[1]/section/div/div[3]/form/div/div[2]/b/div[2]/div/label').click
      page.label(:xpath => '/html/body/div[1]/section/div/div[3]/form/div/div[2]/b/div[3]/p/label').click
    
      # canvas element
      canvas = page.browser.driver.find_element(:xpath => "/html/body/div[1]/section/div/div[3]/form/div/div[2]/b/div[6]/div[1]/div/canvas")
      page.browser.driver.action.move_to(canvas, 50, 20).click_and_hold.move_to(canvas, 550, 85).release.perform
      page.browser.driver.action.move_to(canvas, 200, 85).click_and_hold.move_to(canvas, 75, 43).release.perform
      page.button(id: /btn_send/).click
    
      validate_success(page)
    end
    
    폼이 완성된 후, 나는 그것이 성공적으로 실행되었는지 검증했다.
    이 특정 사이트의 경우 모든 오류 메시지가 사이트에 있지만 CSS 클래스hidden 뒤에 숨겨져 있습니다.오류가 발생하면 클래스 hidden 를 삭제하고 오류 메시지를 표시합니다.
    이와 같이 성공 메시지에서 hidden 클래스를 삭제하면 폼이 성공적으로 제출되었음을 나타냅니다.
    def validate_success(page)
      check_for_errors(page)
    
      if page.label(class: /answer_send color-red/).present?
        puts "Sent form successfully"
      end
    end
    
    def check_for_errors(page)
      if page.label(class: /fill_answer1 color-red/).present?
        puts "First checkbox not checked properly"
      end
    
      if page.label(class: /fill_answer2 color-red/).present?
        puts "Second checkbox not checked properly"
      end
    
      if page.label(class: /fill_sign color-red/).present?
        puts "Signature not recorded properly"
      end
    
      if page.label(class: /answer_send color-red hidden/).present?
        puts "Form not sent successfully"
      end
    end
    
    마지막으로, 나는 하위 목록 교체에서 인용하는 방법#check_already_submitted?을 포함해야 하지만, 아직 구축되지 않았다.
    def check_already_submitted?(page)
      page.link(:class => [
        'answer_send',
        'pdf_wrap_create_briut',
        'padding-right-lg-x',
        'cursor-pointer'
        ]).present?
    end
    
    이제 이 파일은 입구점을 호출하고 마지막 새 줄에 call(ENV['URL']) 을 추가하기만 하면 됩니다.
    응용 프로그램이 실행될 준비를 하기 전에, 우리는 .env 파일에 정확한 변수가 포함되어 있는지 확인해야 한다. 즉,
  • URL: 건강표의 사이트 입구점
  • USERNAME: 사용자 이름
  • PASSWORD: 비밀번호
  • 우리는 파일 상단에 몇 개의 require 문장을 추가해야 한다.
    require 'dotenv'
    Dotenv.load!
    
    require 'webdrivers/chromedriver'
    require 'watir'
    
    현재 우리는 명령줄에서 실행bundle exec ruby declare.rb하고 폼이 자동으로 작성되는 것을 볼 수 있습니다!
    보고 싶지 않으면 headless 에서 true#get_sign_in_page 로 변경하면 백그라운드에서 실행됩니다.
    이 응용 프로그램의 코드는 GitHub 에서 찾을 수 있습니다.
    자동화 즐거움!

    좋은 웹페이지 즐겨찾기