Ruby: парсинг и модификация WEB страниц с Nokogiri и Mechanize

Парсить страницу через curl + regexp можно, но только в простых сценариях. В противном случае проще и надежнее использовать библиотеки.

Mechanize и Nokogiri похожи. Насколько я понимаю Mechanize использует Nokogiri для своей работы. Оба Gem могут использовать html объекты для парсинга/манипуляции (nokogiri так же может работать с xml). Основной косяк их обоих – отсутствие поддержки js. Для этого нужно использовать phantomjs или что-то новое вроде headless chrome.

Пример вывода title для страницы с nokogiri.

require 'nokogiri'
require 'open-uri'

html_page = Nokogiri::HTML(open("http://www.weril.me/"))
puts html_page.title

Можно искать в тегах.

puts html_page.search("p")
Cookies
Использование cookie файла для mechanize очень удобная штука. Особенно когда авторизация по JS с куки файлом и механайз просто ее пройти не сможет.
Генерируем куки
`/usr/bin/phantomjs --cookies-file=cookies.txt --ignore-ssl-errors=true --load-images=false --ssl-protocol=any login.js <login> <pass>`
Используем
cookie_file = 'cookies.txt'
a = Mechanize.new
cookie_val = `grep cookies #{cookie_file} | sed 's/.*dmn=//' | sed 's/;.*//'`.strip
cookie = Mechanize::Cookie.new :domain => 'mydomain.net', :name => 'domain_id', :value => "#{cookie_val}", :path => '/', :expires => (Date.today + 1).to_s
a.cookie_jar << cookie
Ошибки Mechanize

Ошибка “SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed ” или “`post_connection_check’: hostname does not match the server certificate (OpenSSL::SSL::SSLError)” при парсинге

Возникала на старых версиях ruby. Причем возникала не постоянно. Для лечения обновить версию или отключить проверку SSL.

a.verify_mode = OpenSSL::SSL::VERIFY_NONE 

Ошибка “Failed to build gem native extension” при установке Ruby Gem’а Mechanize (mkmf.rb can’t find header files for ruby at /usr/lib/ruby/ruby.h или другие причины)

Mechanize требует огромное количество зависимостей для корректной установки, без них установка будет завершаться ошибкой “Failed to build gem native extension” с различными причинами в описании.

Fix на ubuntu/centos:

sudo apt-get install ruby-dev gcc g++ make
sudo apt-get install build-essential libstdc++6
sudo apt-get install zlib1g-dev
sudo yum install zlib-devel gcc gcc-c++ ruby-devel rubygems

Может так же не ставится из-за того, что другие гемы требуют ruby большей версии, чем та, которая установлена в системе. Тогда обновляем ruby (лучше) или ставим те версии, которые поддерживают наш ruby.

ubuntu@ip-172-31-21-155:~$ sudo gem install mechanize
Fetching: net-http-digest_auth-1.4.1.gem (100%)
Fetching: mime-types-data-3.2018.0812.gem (100%)
ERROR: Error installing mechanize:
mime-types-data requires Ruby version >= 2.0.

ubuntu@ip-172-31-21-155:~$ sudo gem install mechanize -v 2.7.3
Building native extensions. This could take a while...
Fetching: unf-0.1.4.gem (100%)
Fetching: domain_name-0.5.20180417.gem (100%)
Fetching: http-cookie-1.0.3.gem (100%)
Fetching: mini_portile2-2.4.0.gem (100%)
Fetching: nokogiri-1.9.1.gem (100%)
ERROR: Error installing mechanize:
nokogiri requires Ruby version >= 2.1.0.

ubuntu@ip-172-31-21-155:~$ sudo gem install nokogiri -v 1.6.6.2
ubuntu@ip-172-31-21-155:~$ sudo gem install mechanize -v 2.7.3

Leave a Reply