iT邦幫忙

DAY 8
1

回應鐵人賽的文章變鐵人系列 第 8

[Reply] 用ruby實作簡單的wget

jason860421的VC# 網路(遊戲)程式設計 由淺入深 (4)
– System.Net.WebClient說明與實作

示範了怎麼製作GUI的簡單功能的web client的下載工具,
乍看之下,不曉得會不會有覆蓋同檔名的疑慮?
讓我連想到wget處理下載同檔名的處理方式。
剛開始會覺得,
每個作業系統都已經有瀏覽器,
甚至連linux都內建了wget,
或者裝有curl, lynx, links,
若有裝perl的libwww,
還附帶了:lwp-download lwp-mirror lwp-request lwp-rget
這幾個可以query或下載的script,
何需要寫個web client的程式?

如果在一個系統,
就是都沒有上述任何可下載的web client的情況下,
而只有程式語言的話,
自己能不能寫個簡單的 web client,
再去抓適合本身的安裝套件,
就的確需要知道如何寫個web client,
來方便抓東西下來。

平常最常用wget,
直接就把檔案存於所在的目錄中,
如果有同檔名,
就會檔名後多加1的檔尾名,
以免覆蓋原有的檔案。

用ruby模仿做類似功能的rget.rb:

require 'net/http'
require 'uri'
url = URI.parse(ARGV[0])
host = url.host
if url.path.empty? || url.path == '/'
  path = '/'
  filename = 'index.html'
else
  path = url.path
  arr = path.split('/')
  filename = (path.split('/'))[arr.size - 1]
end

def add_one(filename)
  if filename =~ /(.*)\.(\d+)$/
    return $1 + '.' + ($2.to_i + 1).to_s
  else
    return filename + '.1'
  end
end

def have_file(filename)
  return File.readable?(filename)
end

def myoutput(filename)
  if have_file(filename)
    myoutput(add_one(filename))
  else
    return filename
  end
end

http = Net::HTTP.new(host)
headers, body = http.get(path)
if headers.code == "200"
  save_name = myoutput(filename)
  File.open("#{save_name}", "wb") do |f|
    f.write(body)
  end
  puts "Save as #{save_name}"
else
  puts path
  puts "#{headers.code} #{headers.message}"
end

第五行等於是 http://ithelp.ithome.com.tw || http://ithelp.ithome.com.tw/
設其路徑為/,其檔名是index.html,若不是的話,就用原抓到的路徑,及原檔名。

10,11行是抓路徑最後的檔名。
14-20行,判斷若以數字為檔尾名,則以該數字加1,
若檔尾名非數字,則加1。
22-24行,判斷檔名存不存在。
26-32行,輸入檔名後,判斷檔若存在,則再加1,再以遞迴呼叫本身;
判斷檔名不存在則反回檔名。用recursive的方式來看最後應以什麼檔名來輸出。

34-44就只是很簡單地連上該網址,
並自動存成上述判斷後的預設檔名。

所以執行起來會像是這樣子:

$ ruby rget.rb http://ithelp.ithome.com.tw
Save as index.html
$ ruby rget.rb http://ithelp.ithome.com.tw
Save as index.html.1
$ ruby rget.rb http://ithelp.ithome.com.tw
Save as index.html.2

系列文章


上一篇
[Reply] 不會有安全的資料或傳遞,除非用加密的方式
下一篇
[Reply]用ruby 來刮除不必要的HTML標籤
系列文
回應鐵人賽的文章變鐵人30

尚未有邦友留言

立即登入留言