【Ruby】Selenium에서 스크래핑 할 때 발생하기 쉬운 몇 가지 오류 5 선과 그 대처법

Web 스크래핑에 도움이 되는 툴 「Selenium」을 사용할 때에 일어나기 쉬운 에러 5선을 정리했습니다.

환경


  • mac OS Catalina 10.15.6
  • Ruby 2.6.3
  • Rails 6.0.3.2

  • 소개



    Selenium은 복잡한 작업을하는 웹 스크래핑 때 도움이 gem입니다.

    Ruby로 웹 스크래핑 할 때 사용할 수있는 gem
  • Nokogiri (기본)
  • Mechanize (간단)
  • Selenium (브라우저 조작으로 여러가지 가능)

  • Nokogiri와 Mechanize에서는 HTML 태그와 CSS를 지정하여 페이지 내용을 검색합니다.
    Selenium에서는 프로그램에서 브라우저를 열고 의사적으로 조작할 수 있으므로 복잡한 처리가 가능합니다.
  • 로그인이 필요한 경우
  • JavaScript로 페이지를 그리는 경우
  • 데이터를 입력하려면

  • 등 HTML 태그나 CSS 셀렉터만으로는 필요한 정보를 얻을 수 없는 경우에 사용하면 편리합니다.

    Selenium 사용법



    Selenium의 사용법은 여러분이 정리해 주고 있으므로 그쪽을 봐 주세요.

    [루비] selenium에서 Chrome을 사용한 웹 스크래핑

    Selenium 치트 시트 [Ruby]
    # Selenium使用に必要なツールをインストール
    require 'selenium-webdriver'
    
    # Seleniumを起動
    driver = Selenium::WebDriver.for :chrome
    

    Selenium을 사용할 때 특정 오류 5선



    1. 브라우저와 Selenium을 실행하는 도구의 버전이 다릅니다.


    Selenium::WebDriver::Error::SessionNotCreatedError (session not created: This version of ChromeDriver only supports Chrome version 75)
    

    Selenium은 브라우저 유형을 지정하여 프로그래밍 방식으로 마우스를 움직입니다.
    # seleniumの起動
    driver = Selenium::WebDriver.for :chrome
    

    Chrome을 사용하려면 Chrome과 동일한 버전의 Chromedriver를 설치하세요.
    Firefox 및 Chrome과 같이 사용하려는 브라우저를 개발 환경에 설치해야 합니다.

    Google 크롬 버전 확인 방법
    Google 크롬 설정 > 도움말 > Google 크롬 정보에서 버전 확인


    Chromedriver 설치 방법
    [루비] selenium에서 Chrome을 사용한 웹 스크래핑

    Heroku에 배포하고 사용하는 경우 Heroku에도 Google 크롬과 Chromedriver를 설치해야합니다.
    또한 Chrome을 헤드리스로 이동하는 옵션을 추가해야 합니다.
    Heroku에 Chrome과 Chrome 드라이버를 넣어 둡니다.

    [무료] Chrome headless + selenium을 heroku로 정기 실행

    Heroku의 rails 앱에서 헤드리스 크롬을 사용하여 웹 페이지의 스크린 샷을 찍습니다.

    2. 웹 페이지를 열 수 없습니다.


    Selenium::WebDriver::Error::InvalidArgumentError (invalid argument: 'url' must be a string)
    

    좋은 예 : 변수로 전달


    # URLを開く
    @url = 'https://www...'
    driver.get(@url)
    driver.get("#{@url)")
    

    () 안이 ruby의 변수라면 안 되는가?
    문자열에 화가났다.

    좋은 예 : 문자열을 그대로 씁니다.


    # URLを開く
    driver.get('https://www...')
    

    3. 페이지의 요소를 잘 얻지 못했습니다.


    Selenium::WebDriver::Error::NoSuchElementError: no such element: Unable to locate element: {"method":"id","selector":"#entryBtn"}
    

    HTML/CSS에 해당하는 요소가 없을 때 발생하는 오류입니다.
    클래스명 등을 제대로 지정할 수 있는지 체크.

    nokogiri의 경우 : CSS 선택기에서 요소 지정



    CSS 선택기에서 검색할 요소를 지정합니다.
    # nokogiri使用に必要なツールをインストール
    require 'nokogiri'
    require 'open-uri'
    
    # Nokogiriを使用してページの要素を取得
    html = Nokogiri::HTML(open('https://www.google.co.jp/'))
    logo = html.css('#hplogo')
    

    selenium의 경우 : 요소 유형 + 요소 이름 (HTML 태그, CSS 클래스 이름 등)으로 요소 지정



    요소 유형 + 요소 이름으로 검색할 요소를 지정합니다.
    # selenium使用に必要なツールをインストール
    require 'selenium-webdriver'
    
    # Seleniumを起動してページの要素を取得
    driver = Selenium::WebDriver.for :chrome
    driver.find_element(:id, 'hplogo') 
    

    selenium이라면 '#'이 필요 없다.

    4. 페이지에 없는 Selenium 요소에 대해 작업 중


    Selenium::WebDriver::Error::StaleElementReferenceError (stale element reference: element is not attached to the page document)
    

    브라우저백하여 이전 페이지에 있던 요소에 대해 조작하려고 할 때 발생한 오류.

    좋은 예 : 루프의 두 번째 이후 변수가 비어 있습니다.


    # selenium使用に必要なツールをインストール
    require 'selenium-webdriver'
    
    # Seleniumを起動
    driver = Selenium::WebDriver.for :chrome
    
    # イベント一覧ページからイベント詳細ページのURLを取得する
    events = driver.find_elements(:class, 'eventItem')
    
    # イベント詳細ページへ移動する
    for i in 0..events.size()-1
      # イベント詳細ページへのボタンをクリック
      events.find_element(:class, 'entryBtn').click()
     # →2回目以降のループ処理でエラーになる
    
      # 前のページに戻る
     driver.navigate.back
    end
    

    좋은 예 : 루프 처리에서 요소를 다시 검색


    # selenium使用に必要なツールをインストール
    require 'selenium-webdriver'
    
    # Seleniumを起動
    driver = Selenium::WebDriver.for :chrome
    
    # イベント一覧ページからイベント詳細ページのURLを取得する
    events = driver.find_elements(:class, 'eventItem')
    
    # イベント詳細ページへ移動する
    for i in 0..events.size()-1
      # 2回目以降のループ処理の際にドライバがなくなってるので、再度ドライバ指定
      events_in_loop = driver.find_elements(:class, 'prfItem')
    
      # イベント詳細ページへのボタンをクリック
      events_in_loop[i].find_element(:class, 'entryBtn').click()
    
      # 前のページに戻る
     driver.navigate.back
    end
    

    루프하고 있으면 드라이버가 유효하지 않게 되어 버리므로, 루프 내에서 다시 드라이버를 다시 취득할 필요가 있다.

    참고
    get StaleElementReferenceException error while using driver.navigate().back() in a loop in selenium

    5. Ruby 명령을 입력 할 수 없습니다.



    「끝난~」라고 하는 느낌의 환경 구축계 에러입니다.
     `require': incompatible library version - /Users/cathy/Desktop/work/vagrant/Test/vendor/bundle/ruby/2.5.0/gems/pg-0.19.0/lib/pg_ext.bundle (LoadError)
    

    gem을 제거하면 다른 오류가 나오고 빠져 나올 수 없습니다 ...
    /Users/cathy/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- rubygems/core_ext/kernel_warn (LoadError)
    

    Selenium의 gem이 없어져 버렸는데 require 'selenium-driver'의 기술이 있는 것이 원인인 것 같다?

    gem 파일 cannot load such file

    여러가지 해도 해결되지 않기 때문에, 결국 Ruby의 버전을 올리면 어떻게든 움직이게 되었습니다.

    Ruby 버전을 올렸을 때 망설이는 곳

    좋은 웹페이지 즐겨찾기