Lチカ開発ブログ

https://l-chika.com/の開発ブログ

Mechanizeでリンクをスクレイピング

Mechanize を利用したときのメモ。

Mechanize を試した理由

  • ちょっと前は anemone を利用していたが、最近はメンテしてないみたい。
  • 内部でNokogiri を利用しているので、学習・導入コストが個人的に低かった。

よく利用する関数と戻り値の型をメモ

> mechanize = Mechanize.new
> search_page = mechanize.get(url)

> search_page.class
=> Mechanize::Page
> search_page.links.first.class
=> Mechanize::Page::Link
> search_page.links.second.uri
=> #<URI::Generic /a/b.html>
> search_page.links.second.resolved_uri
=> #<URI::HTTP http://hoge.jp/a/b.html>


> div = search_page.search('.hoge')
> div.class
=> Nokogiri::XML::NodeSet
> div.first.class
=> Nokogiri::XML::Element

利用例

links 関数でドキュメント内の a タグを簡単に取得できる。

Mechanizeをラッパーしたリンク取集クラス

class Scraper
  attr_accessor :mechanize

  def initialize
    @mechanize = Mechanize.new
  end

  def scraping_links(url:, links_pattern:, sleep: 1)
    result_links = {}

    loop do
      Rails.logger.debug(url)
      search_page = mechanize.get(url)
      target_links = search_page.links.select { |link| link.uri.to_s =~ links_pattern }
      links = target_links.map { |link| [link.resolved_uri.to_s, link] }.to_h
      result_links.merge!(links)

      next_link = block_given? ? yield(search_page) : nil
      break if next_link.blank?
      url = next_link.resolved_uri.to_s
      sleep(sleep)
    end

    result_links
  end

  def search_document(url)
    search_page = mechanize.get(url)
    yield(search_page)
  end
end

呼び出し例

# http://hoge.jp ページ内の /foo/ のリンクを全て取得したい場合
links = Scraper.new.scraping_links(url: 'http://hoge.jp', links_pattern: /foo/)

# http://hoge.jp ページ内の /foo/ のリンクをページングして全て取得したい場合。この場合は「次へ」のリンクがなくなるまでクロール
links = Scraper.new.scraping_links(url: 'https://hoge.co.jp/foos/?page=1',
                                  links_pattern: /foos\/[A-Z]/) do |search_page|
             search_page.links.find { |link| link.text == '次へ' }
            end

おすすめ本

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

PythonによるWebスクレイピング

PythonによるWebスクレイピング