over 1 year ago

接續 RailsFun_新手教學_day1 _HD

參考:Parsing HTML with Nokogiri

北醫:

北醫的首頁:http://www.tmuh.org.tw/
產科的首頁:http://www.tmuh.org.tw/team/team/053
A醫生的個人頁面:http://www.tmuh.org.tw/team/team/053/053/050216
B醫生的個人頁面:http://www.tmuh.org.tw/team/team/053/053/050117

這兩個要先require
require 'open-uri'
require 'nokogiri'
terminal:由產科的首頁,先抓下來兩個網址
html = open('http://www.tmuh.org.tw/team/team/053').read
doc = Nokogiri::HTML(html)
new_html = doc.css(".media-left a").map{|link| link['href']}
temp_ans = new_html.map{|url| url.match(/^htpp/) ? url : "http://www.tmuh.org.tw#{url}"}
=> ["http://www.tmuh.org.tw/team/team/053/053/050216", "http://www.tmuh.org.tw/team/team/053/053/050117"]
terminal:先試看看抓醫生的名字下來
doctors = []
temp_ans.each do |f|
html = open(f).read
doc = Nokogiri::HTML(html)
doctors << {
name: doc.xpath('//h2').text
}
end
doctors
[{:name=>"區慶建 "}, {:name=>"簡立維 "}]
doctors[0][:name]
=> "區慶建 "
terminal:先試看看抓學歷這個項目名稱下來
doc.css('.col-sm-8 > p > span > strong')[0].text
=> "學歷"
doc.xpath('//strong')[0].text
=> "學歷"
terminal:用css去找
doc.css('.media > .media-left > a > img')
terminal
irb(main):001:1> imgs.each do |img|
irb(main):002:1* puts img.attr('src')
irb(main):003:1> end; true
terminal:抓產科首頁的兩個醫生的照片
doc.css(".media-left a")
terminal:把 a tag 的href拿掉的兩種方法
doc.css(".media-left a").map{|link| link['href']}
p doc.xpath('//div[@class="heat"]/a').map { |link| link['href'] }
terminal:用wget 把檔案抓到指定的資料夾 wget -P 資料夾路徑 檔案網址
wget -P /Users/tienshunlo/workspace/broadway/app/assets/images http://www.tmuh.org.tw//UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg

抓A醫生的個人頁面

準備工作做好
require 'open-uri'
require 'nokogiri'
html = open('http://www.tmuh.org.tw/team/team/053/053/050117').read
doc = Nokogiri::HTML(html)
1. 把名字找出來
把名字找出來
name = doc.css('//h2').text.strip
2. 把所有跟學歷、經歷、證照相關的項目找出來
把所有跟學歷、經歷、證照相關的項目找出來
regex =  doc.css('.col-sm-8 > p').to_html
ans = []
ans = regex.scan(/>([^\n><]+)</).flatten.map{|i| i.gsub(/•/ , '').gsub(/&nbsp;/ , '').gsub(/\u00a0/, '').strip}.delete_if{|i|i.empty?}

解釋:
- 要用to_html,把Nokogiri::XML::NodeSet轉成html,不然沒辦法用scan
- 參考Nokogiri 問題求救
- Regex

把相關項目按學歷、經歷、證照分類
temp = []
ans.each do |str|
    case str
    when "學歷" , "經歷" , "專科證書名稱"
        temp << []
    else
        temp[-1] << str
    end
end
terminal:最後結果會變這樣
temp
=> [["臺北醫學大學醫學系"], ["臺北醫學大學附設醫院 超音波科主任", "臺北醫學大學副教授"], ["婦產科專科醫師證書", "超音波專業醫師證書", "台灣周產期專科醫師證書"], ["臺北醫學大學醫學系"], ["臺北醫學大學附設醫院 超音波科主任", "臺北醫學大學副教授"], ["婦產科專科醫師證書", "超音波專業醫師證書", "台灣周產期專科醫師證書"]]
3. 抓照片的URL:方法三應該最直接,直接找ID
terminal:#方法一
img = doc.css('img#MainPlaceHolder_imgPhoto')
img_url = img.attr('src')
puts img_url
terminal:#方法一 / 結果
=> [#<Nokogiri::XML::Element:0x3fcc0e534b24 name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e534a70 name="id" value="MainPlaceHolder_imgPhoto">, #<Nokogiri::XML::Attr:0x3fcc0e534a20 name="src" value="/UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg">]>]

=> #<Nokogiri::XML::Attr:0x3fcc0e534a20 name="src" value="/UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg">

=> /UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg
terminal:#方法二
img_url = doc.css('img').css('#MainPlaceHolder_imgPhoto').attr('src')
terminal:#方法二 / 結果
=> /UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg
terminal:#方法三
img = doc.css('#MainPlaceHolder_imgPhoto')
img_url = img.attr('src')
puts img_url
terminal:#方法三 / 結果
=> [#<Nokogiri::XML::Element:0x3fe86791b13c name="img" attributes=[#<Nokogiri::XML::Attr:0x3fe86791b0d8 name="id" value="MainPlaceHolder_imgPhoto">, #<Nokogiri::XML::Attr:0x3fe86791b0c4 name="src" value="/UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg">]>]

=> #<Nokogiri::XML::Attr:0x3fcc0e534a20 name="src" value="/UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg">

=> /UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg
terminal:#方法四 - 1
img = doc.css('img')
img.count
terminal:#方法四 - 1 / 結果
=> [#<Nokogiri::XML::Element:0x3fcc0e1a5b70 name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e1a5b0c name="class" value="tmuh_logo">, #<Nokogiri::XML::Attr:0x3fcc0e1a5af8 name="src" value="/images/logo.jpg">, #<Nokogiri::XML::Attr:0x3fcc0e1a5ae4 name="alt" value="回首頁">]>, #<Nokogiri::XML::Element:0x3fcc0e534b24 name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e534a70 name="id" value="MainPlaceHolder_imgPhoto">, #<Nokogiri::XML::Attr:0x3fcc0e534a20 name="src" value="/UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg">]>, #<Nokogiri::XML::Element:0x3fcc0e5184ec name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e518474 name="src" value="/images/logo.jpg">, #<Nokogiri::XML::Attr:0x3fcc0e518460 name="style" value="width: 100%;">]>, #<Nokogiri::XML::Element:0x3fcc0e1716cc name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e171668 name="src" value="/images/badge.jpg">, #<Nokogiri::XML::Attr:0x3fcc0e171654 name="style" value="width: 100%;">]>]

=> 4
terminal:#方法四 -2
img[0]
img[1]
img[2]
img[3]
terminal:#方法四 -2 / 結果:img[1]才是要找的醫生照片
=> #<Nokogiri::XML::Element:0x3fcc0e1a5b70 name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e1a5b0c name="class" value="tmuh_logo">, #<Nokogiri::XML::Attr:0x3fcc0e1a5af8 name="src" value="/images/logo.jpg">, #<Nokogiri::XML::Attr:0x3fcc0e1a5ae4 name="alt" value="回首頁">]>

=> #<Nokogiri::XML::Element:0x3fcc0e534b24 name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e534a70 name="id" value="MainPlaceHolder_imgPhoto">, #<Nokogiri::XML::Attr:0x3fcc0e534a20 name="src" value="/UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg">]>

=> #<Nokogiri::XML::Element:0x3fcc0e5184ec name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e518474 name="src" value="/images/logo.jpg">, #<Nokogiri::XML::Attr:0x3fcc0e518460 name="style" value="width: 100%;">]>

=> #<Nokogiri::XML::Element:0x3fcc0e1716cc name="img" attributes=[#<Nokogiri::XML::Attr:0x3fcc0e171668 name="src" value="/images/badge.jpg">, #<Nokogiri::XML::Attr:0x3fcc0e171654 name="style" value="width: 100%;">]>
terminal:#方法四 -3
img_url = img[1]['src']
terminal:#方法四 -3 / 結果
=> "/UploadFile/EMPLOYEE/20150908192641028_%e7%b0%a1%e7%ab%8b%e7%b6%ad_1.jpg"
4. 用wget抓下照片
terminal:記得要用``
profile_img = "http://www.tmuh.org.tw#{img_url}"
`wget --output-document="/Users/tienshunlo/workspace/broadway/app/assets/images/123.jpg" --directory-prefix="/Users/tienshunlo/workspace/broadway/app/assets/images"  #{profile_img}`
`wget -P /Users/tienshunlo/workspace/broadway/app/assets/images -O /Users/tienshunlo/workspace/broadway/app/assets/images/123.jpg  #{profile_img}`

解釋:
wget記得要用``包起來。
-P 是指定資料夾 ( --directory-prefix=)
-O 是改變檔案名稱 (--output-document=)
誰先寫無所謂,但一定要記得寫出完整的路徑,要被下載的路徑要擺最後。

5. 新增Play
terminal
@play = Play.new
        @play.title = name
        @play.play_img = File.open("app/assets/images/#{name}.jpg",'r')
        #File.new("/path/to/image.jpg","r")

        #File.open('/path/to/image.jpg', 'r'))

        @play.category = Category.first
        @play.director = temp[1].join("<p>")
        @play.description = temp[2].join("<p>")
        @play.save

解釋:
Paperclip Gem:一般來講,用Paperclip上傳檔案,會存三種大小的檔案在Project_name/public/system/裡面,
所以要用File.open的方法去找到用wget存下來的路徑。

6. 純.rb檔放置地方

參考:RailsFun.tw 新手教學 day3 HD:大概在53分鐘的地方
a. JC.rb檔案做在project_name/lib
b. 剛做好的時候,可以用ruby JC.rb
c. 然後到config/application.rbrequirerequire "JC" (不要有.rb)
d. require之後,可以用rails c試看看,先require "JC",然後再JC.run (我是設定self.run)
e. 還可以到view去使用 <%= JC.run %>,不過server記得要重開

JC.rb的寫法,放在lib folder,要先require
require 'open-uri'
require 'nokogiri'
class JC
    def self.run
        html = open('http://www.tmuh.org.tw/team/team/053/053/050216').read
        doc = Nokogiri::HTML(html)
        #名稱

        name = doc.css('//h2').text.strip     
        #圖檔

        img = doc.css('#MainPlaceHolder_imgPhoto')
        img_url = img.attr('src')
        profile_img = "http://www.tmuh.org.tw#{img_url}"
        `wget -P /Users/tienshunlo/workspace/broadway/app/assets/images -O /Users/tienshunlo/workspace/broadway/app/assets/images/#{name}.jpg  #{profile_img}`
        #學歷、經歷、專科證書名稱

        ans = []
        ans = doc.css('.col-sm-8 > p').to_html.scan(/>([^\n><]+)</).flatten.map{|i| i.gsub(/•/ , '').gsub(/&nbsp;/ , '').gsub(/\u00a0/, '').strip}.delete_if{|i|i.empty?}
        temp = []
        ans.each do |str|
          case str
          when "學歷" , "經歷" , "專科證書名稱"
            temp << []
          else
            temp[-1] << str
          end
        end
        #新增Play

        @play = Play.new
        @play.title = name
        @play.play_img = File.open("app/assets/images/#{name}.jpg",'r')
        @play.category = Category.first
        @play.director = temp[1].join("<p>")
        @play.description = temp[2].join("<p>")
        @play.save
    end
end
← 如何使用Git 用 mechanize gem 去爬 google search page (next page) →