Scrapage automatique avec le service "2Captcha" qui traverse "CAPTCHA" et Ruby + Chrome_Remote

introduction

Quand je grattais, je pense avoir eu l'expérience que CAPTCHA est sorti et que le programme s'est arrêté. (Seules ces personnes verront cet article.) Afin d'éviter CAPTHCA d'une manière ou d'une autre, il existe des moyens de le faire bouger comme la distribution BOT ou IP, mais cette fois, je vais essayer de résoudre CAPTCHA docilement. Bien sûr, puisque je suis ingénieur, je souhaite le résoudre automatiquement sur le programme plutôt que de le résoudre moi-même. L'apprentissage automatique a des coûts d'apprentissage et d'introduction élevés, et je souhaite en profiter encore plus. Un service appelé 2Cpathca rend cela possible. Il existe de nombreux autres services, alors trouvez celui qui vous convient le mieux. Il y avait un article Python, mais je n'ai pas trouvé d'article Ruby, alors je l'ai écrit.

Qu'est-ce que 2Capthca

image.png C'est un service pour percer la fonction CAPTHCA, et l'authentification peut être automatisée à l'aide de l'API. C'est un service payant, mais reCAPTCHA v2 est aussi bon marché que 2,99 $ pour 1000 demandes. Pour rappel, il n'y a pas d'échange d'argent entre moi et 2Captcha à des fins promotionnelles.

Qu'est-ce que Chrome_Remote?

Une bibliothèque qui vous permet d'exploiter des instances Chrome à partir de Ruby. Veuillez consulter la page d'explication et Repository pour une utilisation détaillée. En tant que prémisse pour le grattage, il est nécessaire de rendre difficile l'apparition de CAPTHCA en premier lieu. Contrairement à Selenium, etc., Chrome_Remote qui exécute Chrome car il est plus difficile de juger BOT. (Je veux vérifier la différence bientôt.)

Chose que tu veux faire

image.png Parcourez la page de démonstration reCAPTCHA. 2 Veuillez vous reporter à l'article du prédécesseur pour créer un compte Capthca et obtenir une clé API.

Percer reCAPTHCA avec "2Captcha" et Ruby + Chrome_Remote

2 Obtenez la clé api Captcha et enregistrez-la sous forme de fichier.

key.yaml


---
:2Capthca:2 Touche api Captcha

Lancez Chrome avec debugging-port.

Pour Mac


/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 &

Installez le Gem requis.

Gemfile


source "https://rubygems.org"
gem 'nokogiri'
gem 'chrome_remote'
bundle install

Le programme ruby lui-même.

crawler.rb



require 'nokogiri'
require 'chrome_remote'
require 'yaml'

class CaptchaDetectedException < StandardError; end

class ChromeController
  def initialize
    @chrome = ChromeRemote.client

    # Enable events
    @chrome.send_cmd "Network.enable"
    @chrome.send_cmd "Page.enable"
  end
  
  def open(url)
    #Accès à la page
    move_to url
    captcha_detect
  end
  
  def reload_page
    sleep 1
    @chrome.send_cmd "Page.reload", ignoreCache: false
    wait_event_fired
  end
  
  def execute_js(js)
      @chrome.send_cmd "Runtime.evaluate", expression: js
  end
  
  def wait_event_fired
      @chrome.wait_for "Page.loadEventFired"
  end
  
  #Navigation dans la page
  def move_to(url)
    sleep 1
    @chrome.send_cmd "Page.navigate", url: url
    wait_event_fired
  end
  
  #Obtenir du HTML
  def get_html
    response = execute_js 'document.getElementsByTagName("html")[0].innerHTML'
    html = '<html>' + response['result']['value'] + '</html>'
  end
  
  def captcha_detect
    bot_detect_cnt = 0
    begin
      html = get_html
      raise CaptchaDetectedException, 'captcha confirmé' if html.include?("captcha")
    rescue CaptchaDetectedException => e
      p e
      bot_detect_cnt += 1
      p "Tentative de percer le captcha: #{bot_detect_cnt}Temps"
      doc = Nokogiri::HTML.parse(html, nil, 'UTF-8')
      return if captcha_solve(doc) == 'Libération réussie'
      reload_page
      retry if bot_detect_cnt < 3
      p 'erreur de percée captcha. Quitter Ruby'
      exit
    end
    p 'Il n'y avait pas de captcha'
  end

  def captcha_solve(doc)
    id = request_id(doc).match(/(\d.*)/)[1]
    solution = request_solution(id)
    return false unless solution
    submit_solution(solution)
    p captcha_result
  end

  def request_id(doc)
    #Lire la clé API
    @key = YAML.load_file("key.yaml")[:"2Capthca"]
    # data-Obtenez la valeur de l'attribut sitekey
    googlekey = doc.at_css('#recaptcha-demo')["data-sitekey"]
    method = "userrecaptcha"
    pageurl = execute_js("location.href")['result']['value']
    request_url="https://2captcha.com/in.php?key=#{@key}&method=#{method}&googlekey=#{googlekey}&pageurl=#{pageurl}"
    #Demande de libération du captcha
    fetch_url(request_url)
  end

  def request_solution(id)
    action = "get"
    response_url = "https://2captcha.com/res.php?key=#{@key}&action=#{action}&id=#{id}"
    sleep 15
    retry_cnt = 0
    begin
      sleep 5
      #Obtenez le code de déverrouillage captcha
      response_str = fetch_url(response_url)
      raise 'Avant de publier captcha' if response_str.include?('CAPCHA_NOT_READY')
    rescue => e
      p e
      retry_cnt += 1
      p "réessayez:#{retry_cnt}Temps"
      retry if retry_cnt < 10
      return false
    end
    response_str.slice(/OK\|(.*)/,1)
  end

  def submit_solution(solution)
    #Entrez le code de déverrouillage dans la zone de texte spécifiée
    execute_js("document.getElementById('g-recaptcha-response').innerHTML=\"#{solution}\";")
    sleep 1
    #Cliquez sur le bouton Soumettre
    execute_js("document.getElementById('recaptcha-demo-submit').click();")
  end

  def captcha_result
    sleep 1
    html = get_html
    doc = Nokogiri::HTML.parse(html, nil, 'UTF-8')
    doc.at_css('.recaptcha-success') ? 'Libération réussie' : 'Échec de l'annulation'
  end


  def fetch_url(url)
    sleep 1
    `curl "#{url}"`
  end

end

crawler = ChromeController.new
url = 'https://www.google.com/recaptcha/api2/demo'
crawler.open(url)

Lorsque vous exécutez le programme, il accède à la page de démonstration de reCAPTCHA et essaie de percer CAPTCHA.

bundle exec ruby crawler.rb

finalement

En fonction de la finalité et du mode du grattage et de la manière de traiter les données obtenues par grattage, il existe un risque de violation de la loi sur le droit d'auteur et de la loi sur la protection des informations personnelles. Je vous souhaite à tous une bonne vie de grattage

Recommended Posts

Scrapage automatique avec le service "2Captcha" qui traverse "CAPTCHA" et Ruby + Chrome_Remote
[Ruby] 5 erreurs courantes qui ont tendance à se produire lors du scraping avec Selenium et comment les gérer