ウェブ-HACKS 「とりあえずやってみよう!」ブログでタグ「mechanize」が付けられているもの

Rubyのmechanizeでnameにハイフンがあると値を設定できない

   ブックマークに追加する
以前に作ったRubyクローラーを改造して、検索フォームに自動で値を設定するプログラムをつくりました。その際にテキストフィールドのnameにハイフンがあり値の設定にはまったので解決方法を記載します。
以下ですとエラーとなります。 ※keyword-fieldにハイフンが入っているためです。

    page = @agent.get('http://example.com')
    search_form = page.forms.with.action('http://example.com/search.html').first
    search_form.keyword-field = keyword

実は以下のように['keyword-field']とすればOK。簡単です。いろいろ検索したのですが、解決策が探せなかったので、記載してみました。

    page = @agent.get('http://example.com')
    search_form = page.forms.with.action('http://example.com/search.html').first
    search_form['keyword-field'] = keyword

Rubyでクローラー作成(mechanize, hpricot)

   ブックマークに追加する
何度も同じようなプログラム(Rubyでスクレーピング)を作成しているような気がしますが、久々のRubyでクローラー作成。なんでこんなに何度も書くのかというと結構チェックしたいサイトが多く、仕事でも頼まれるためです。

Perlで作成したクローラーはこちら

今回はきっちりクラスらしく作りました。結構汎用的になっているのではないかと思います。簡単なスクリプトです。
ソースはこれまで通りクリエイティブコモンズで。

#!/usr/bin/ruby -Ks
require 'hpricot'
require 'mechanize'
require 'kconv'
$KCODE = 's'

class Crawler
  def initialize(wait_time, internal, ngwords)
    @agent = WWW::Mechanize.new
    @wait_time = wait_time
 @internal = internal
@ngwords = ngwords
 @links = [] end def http_connect(url) print "OK\n" @page = @agent.get(url) end def crawl(root) @page = @agent.get(root) @page.links.with.href(%r{}).each{|link| if link.href =~ /^http/ url = link.href else %r|http://([^/]*)/| =~ root url = 'http://' + $1 + '/' + link.href end @links << url.sub(/#.*$/,'') } @links.uniq!.delete(root) puts @links @links.each{|link| begin print link if $DEBUG next unless access_test?(link) http_connect(link) sleep @wait_time rescue => ex puts ex.message end } end

 private def access_test?(link) unless %r|#{@internal}| =~ link print "External Link.\n" return false end @ngwords.each{|ng| if /#{ng}/ =~ link print "NG Word\n" return false end } true end end

かなり以下のサイト参考になります。何度も読ませて頂きました。

【参考サイト】

Rubyでスクレーピング(mechanizeとhpricot)

   ブックマークに追加する
以前にPerlでクロールするプログラムを作ったので、勉強がてら今回はRubyで作成してみました。ただ今回はかなり、てこずりました。文字コード?のところではまってしまい作るのにまるまる1日かかりました。まずは出来上がったコード。

【事前準備】


$ gem install hpricot
$ gem install mechanize

【ソースコード】


#!/usr/bin/ruby -Ks
require 'hpricot'
require 'mechanize'
require 'kconv'
require 'jcode'

$KCODE = 's'

# 初期設定
@user_agent = 'Mac Safari'
@wait_time = 5
@url = 'taget_url'

def http_connect(url, keyword)
  puts url if $DEBUG
  @page = nil;@price = nil;@content = ""
  begin
    @agent = WWW::Mechanize.new
    @agent.user_agent_alias = @user_agent
    @page = @agent.get(url)
  rescue
    puts "#{keyword}#{@drim}CONNECTION ERROR"
    return
  end
  link = @page.links.with.href(%r{http://target_url/\w+?/}).last
  puts link.href if $DEBUG
  if(link == nil || link.href.empty?)
    puts "#{keyword}#{@drim}LINKERROR"
    return
  end
  @page = @agent.click(link)
  doc = @page.root
  @name = (doc/"span.item_name").inner_html.tosjis
  (doc/"span.item").each {|item|
    item_str = item.inner_html.tosjis
    item_str.scan(/
(.*?)<\/div>
(.*?)<\/div>/){|title, content| @content += ":#{title}:#{content}" # if $DEBUG } item_str.scan(/([\d+] 円)/){|price| @price = price } puts "#{keyword}#{@drim}#{@price}#{@drim}#{@name}#{@drim}#{@content}#{@drim}#{link.href}" } end def generate_url puts ARGV[0] if $DEBUG File.open(ARGV[0]){|f| f.each{|line| keyword = line.chomp! puts keyword if $DEBUG target="#{@targeturl}?keyword=#{keyword}" http_connect(target, keyword) sleep @wait_time } } end puts @header generate_url

ECショップの検索結果から商品情報を取得することを想定しているのですが、どうもカタカナの「ッ」が全て文字化けしてしまう。kconvではなくnkficonvを使っても結果はおなじ。解決方法としては以下1行を挿入するだけで文字化けはおきなくなりました。

require 'jcode'

原因はまだ調べているところですが、以下サイトをきちんと理解できればわかると思います。はぁー、大分はまってしまった。

【参考サイト】

RubyでHTTPヘルスチェックプログラムをつくる(mechanizeとnet/smtpを使用する)

   ブックマークに追加する
RubyでHTTPアクセスが正常にできるかどうかを確認するツールを作成しました。
対象のURLにアクセスし、titleの文字列で正常にページアクセスできるかどうか確認しています。
エラー時は指定したメールアドレスにメールをとばすようになっています。

以下にソースコードを記載します。
※下線部は適宜環境にあわせてください

Windows環境でおこないました。
デバッグモードで実行するといくつか警告がでてますね。なんでだろ?
とりあえず動作はします。

【事前準備】
gemsmechanizeをインストールする

    > gem install mechanize


【ソースコード】

#!/usr/bin/ruby
require 'mechanize'
require 'net/smtp'
require 'kconv'

url = "http://localhost/"
wait_time = 15
@from_address = "from@mail_domain"
@send_address = "send@mail_domain"
agent = WWW::Mechanize.new

def send_alert( msg )
  body = [ "Subject: HTTP Access Error\n", "\n", msg ]
  Net::SMTP.start('mail_server') do |smtp|
    smtp.sendmail( body, @from_address, @send_address )
  end
  exit
end

begin
  while 1
    page = agent.get(url)
    s = page.title.tosjis
    if s =~ /match_word/
      puts "#{url}: #{s}\n" if $DEBUG
    else
      puts "#{url}: #{s}=#{match_str.tosjis}\n" if $DEBUG
      send_alert("#{url}: #{s}\n")
    end
    sleep wait_time
  end
rescue => ex
  puts "#{url}: #{ex.message}\n" if $DEBUG
  send_alert("#{url}:#{ex.message}\n")
end

【参考にしたサイトです】


あわせて読みたいブログパーツ
フィードメーター - ウェブ-HACKS 「とりあえずやってみよう!」ブログ   
track feed
  • SEO対策 
  • _ 
  • _ 
  •  
  •  

このブログはクリエイティブ・コモンズでライセンスされています。
Google

Tags