sk

開発で得たこと

5分でRailsでクローラーを作る。【その2】【文字】【ページソース】

文字条件で取得 ---精度70%---

bots_controller.rb

    def if_crawl
        @bot = Bot.find(params[:id])
        doc = Nokogiri::HTML(open("#{@bot.url}"))#URLの指定
            
        doc.css('table').each do |crawl| #テーブルを引っ張る
            @crawl = crawl.inner_html.encode("UTF-8") #↓指定の単語が全て含まれてればtrue
             if @crawl.encode("UTF-8").include?(@bot.word1) && @crawl.encode("UTF-8").include?(@bot.word2) && @crawl.encode("UTF-8").include?(@bot.word3)
                 @if_crawl = crawl.inner_html.encode("UTF-8")
             end
        end
    end

・・・

      private
      
        def bot_params
          params.require(:bot).permit(:name, :url, :xpath, :word1, :word2, :word3) #word1~3を追加
        end

if_crawl.html.erb

<div class="form align">
    <div class="jumbotron font">
        送信に成功しました!
    </div>
    
    送った内容
    <div class="jumbotron padding height">
        <%= "<table>" + @if_crawl.encode("UTF-8") + "</table>" %>
    </div>
    
    プレビュー
    <div class="jumbotron">
        <%= simple_format("<table>" + @if_crawl.encode("UTF-8") + "</table>") %>
    </div>
    
    プレビュー2 #HTMLで表示
        <%= "<table>#{@crawl.encode("UTF-8")}</table>".html_safe %>
</div>
  get 'bots/if_crawl', to: 'bots#if_crawl'

new.html.erb


<div class="col-xs-12">
<table class="type07">
    <thead>
    <tr>
        <th scope="cols"></th>
        <th scope="cols">サイト名</th>
        <th scope="cols">URL</th>
        <th scope="cols">Xpath</th>
        <th scope="cols">取得方法1</th>
        <th scope="cols">取得方法2</th>
    </tr>
    </thead>
    <tbody>
        
    <% @bots.each do |bot| %>

        <tr>
            <th scope="row"><%= bot.id %></th>
    		<td><%= bot.name  %></td>
    		<td><%= bot.url.truncate(20) %></td>
    		<td><%= bot.xpath %></td>
            <td><%= link_to "crawl", bots_crawl_path(id: bot.id) %></td>
            <td><%= link_to "文字条件", bots_if_crawl_path(id: bot.id) %></td>
        </tr>
        
    <% end %>
    </tbody>
</table>
</div>
<div class="form">

  <%= form_for :bot, url: bots_path do |f| %>
    
    <p>
      <%= f.label :name, "サイト名" %><br>
      <%= f.text_field :name, class: 'form-control input-sm', style: "width:500px;", :placeholder => "サイト名"%>
    </p>
   
    <p>
      <%= f.label :url, "URL" %><br>
      <%= f.text_area :url, class: 'form-control input-sm', style: "width:500px;", size: "10", :placeholder => "URL"%>
    </p>
    
    <p>
      <%= f.label :xpath, "Xpath" %><br>
      <%= f.text_area :xpath, class: 'form-control input-sm', style: "width:500px;", size: "10", :placeholder => "xpathで抽出する際に必要になります"%>
    </p>
    
    ###追加###
    <p>
      <%= f.label :word1, "条件ワード1" %><br>
      <%= f.text_area :word1, class: 'form-control input-sm', style: "width:500px;", size: "10", :placeholder => "文字条件抽出に必要になります" %>
    </p>
    
    <p>
      <%= f.label :word2, "条件ワード2" %><br>
      <%= f.text_area :word2, class: 'form-control input-sm', style: "width:500px;", size: "10", :placeholder => "文字条件抽出に必要になります" %>
    </p>
    
    <p>
      <%= f.label :word3, "条件ワード3" %><br>
      <%= f.text_area :word3, class: 'form-control input-sm', style: "width:500px;", size: "10", :placeholder => "文字条件抽出に必要になります" %>
    </p>
    
    ###追加###

    <p>
      <%= f.submit "登録", class: 'btn btn-primary' %>
    </p>
  <% end %>
</div>

テスト

文字を取得

CZkHKxAtzytJcBK1494433908_1494433920.png

結果
プレビュー2
SAMPLE03	プロ
デザイン	スタイルシート
カラー	オレンジ

無理やり抜粋する ---精度90%---


今までのアプローチは必要なものだけを取得するものでしたが、
こちらは一旦全てを取得しそこから、不要なものを削ぎ落としていくものです。

bots_controller.rb

    def slice_crawl
        @bot = Bot.find(params[:id])
        @doc = Nokogiri::HTML(open("#{@bot.url}")).inner_html.encode("UTF-8") #URLの指定
        @index_doc = @doc.index("#{@bot.upper}") 
        @end_doc = @doc.rindex("</html>") - 1 
        @slice_crawl_pre = @doc.slice(@index_doc..@end_doc) 
        @table_doc = @slice_crawl_pre.index("table>") + 5
        @slice_crawl = @slice_crawl_pre.slice(0..@table_doc)
    end

      private
      
        def bot_params
          params.require(:bot).permit(:name, :url, :xpath, :word1, :word2, :word3, :upper) #upper(上段)を追加
        end


取得先のHTMLコードは 〜

〜 という構造ですが、
インデックスでこのtableタグの前後を削ぎます。


routes.rb

  get 'bots/slice_crawl', to: 'bots#slice_crawl'


slice_crawl.html.erb

<div class="form align">
    <div class="jumbotron font">
        取得に成功しました!
    </div>
    
    取得した内容
    <div class="jumbotron padding height">
        <%= @slice_crawl.encode("UTF-8") %>
    </div>
    
    プレビュー
    <div class="jumbotron">
        <%= simple_format(@slice_crawl.encode("UTF-8")) %>
    </div>
    
    プレビュー2
        <%= "<table>#{@slice_crawl.encode("UTF-8")}</table>".html_safe %>
</div>

index.html.erb


<div class="col-xs-12">
<table class="type07">
    <thead>
    <tr>
        <th scope="cols"></th>
        <th scope="cols">サイト名</th>
        <th scope="cols">URL</th>
        <th scope="cols">Xpath</th>
        <th scope="cols">取得方法1</th>
        <th scope="cols">取得方法2</th>
        <th scope="cols">取得方法3</th> #追加
    </tr>
    </thead>
    <tbody>
        
    <% @bots.each do |bot| %>

        <tr>
            <th scope="row"><%= bot.id %></th>
    		<td><%= bot.name  %></td>
    		<td><%= bot.url.truncate(20) %></td>
    		<td><%= bot.xpath %></td>
            <td><%= link_to "crawl", bots_crawl_path(id: bot.id) %></td>
            <td><%= link_to "文字条件", bots_if_crawl_path(id: bot.id) %></td>
            <td><%= link_to "抜粋", bots_slice_crawl_path(id: bot.id) %></td> #追加
        </tr>
        
    <% end %>
    </tbody>
</table>
</div>
    <p>
      <%= f.label :upper, "上段" %><br>
      <%= f.text_area :upper, class: 'form-control input-sm', style: "width:500px;", size: "10", :placeholder => "上段"%>

テスト

対象サイト
html取得

FVg0xCUajBSdzWe1494435139_1494435152.png

結果
プレビュー2
SAMPLE04	デザイン	枠線	カラー
有料	プロ	有り	216色
無料	アマチュア	なし	モノトーン


以上です!

ProgateやRailsチュートリアル、プログラミングスクールを通い終えたが現場のコードはかけない、

一体どうやって書くの?と思っているエンジニアのみなさんのためのチュートリアルを公開しています。

チュートリアル