2013-04-08 203 views
2

我有一堆存儲在數據庫中的HTML內容,我期待將所有相關資產引用轉換爲使用絕對路徑。舉例來說,我所有的圖像標籤都在尋找這樣的事情:用絕對路徑URL替換相對路徑網址

<img src=\"/system/images/146/original/03.png?1362691463\"> 

我想在前面加上「http://mydomain.com」到「/系統/圖片/」位,我有以下的代碼,我希望來處理,但遺憾的是它似乎並沒有產生任何變化:

text = "<img src=\"/system/images/146/original/03.png?1362691463\">" 
text.gsub(%r{<img src=\\('|")\/system\/images\/}, "<img src=\"http://virtualrobotgames.com/system/images/") 
+0

你應該考慮使用專門爲工作而設計的工具:[URI(HTTP://www.ruby-doc。組織/ STDLIB-1.9.3/libdoc/URI /的RDoc/URI.html)。它有方法來解析URL,更改方案和主機,混淆路徑,然後吐出一個正確編碼的字符串。 – 2013-04-08 23:58:14

+0

@theTinMan我喜歡這個想法,如果你把它作爲一個答案,我會高興地接受它。 – Noz 2013-04-09 16:42:46

+0

我添加了一個擴展的例子。 – 2013-04-09 19:28:08

回答

8

相反操作使用普通字符串操作的URL字符串,用於作業的製作工具。紅寶石包括URI類,並有更徹底的Addressable寶石。

這裏的,如果我有一些HTML的鏈接,我想重寫我會怎麼做:

首先,解析文檔:

require 'nokogiri' 
require 'uri' 

SOURCE_SITE = "http://virtualrobotgames.com" 

html = ' 
<html> 
<head></head> 
<body> 
    <img src="/system/images/146/original/03.png?1362691463"> 
    <script src="/scripts/foo.js"></script> 
    <a href="/foo/bar.html">foo</a> 
</body> 
</html> 
' 
doc = Nokogiri::HTML(html) 

然後你在通過行走的位置是您要的文件,並修改標籤,如<a><img><script>和別的:

# find things using 'src' and 'href' parameters 
tags = { 
    'img' => 'src', 
    'script' => 'src', 
    'a'  => 'href' 
} 
doc.search(tags.keys.join(',')).each do |node| 

    url_param = tags[node.name] 

    src = node[url_param] 
    unless (src.empty?) 
    uri = URI.parse(src) 
    if uri.relative? 
     uri.scheme = SOURCE_SITE.scheme 
     uri.host = SOURCE_SITE.host 
     node[url_param] = uri.to_s 
    end 
    end 
end 

puts doc.to_html 

其中,運行後,輸出s:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html> 
<head><meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"></head> 
<body> 
    <img src="http://virtualrobotgames.com/system/images/146/original/03.png?1362691463"><script src="http://virtualrobotgames.com/scripts/foo.js"></script><a href="http://virtualrobotgames.com/foo/bar.html">foo</a> 
</body> 
</html> 

這並不意味着它是一個完整的,完整的例子。這是與絕對鏈接,但你必須處理相對鏈接,與兄弟/同行主機名的鏈接,缺少參數。

您還需要在解析後檢查「doc」的errors方法,以確保它是有效的HTML。解析器可以重寫/修剪無效HTML中的節點,試圖理解它。

+1

你不能在一個字符串上調用URI方法,必須是'URI(SOURCE_SITE).scheme' – Sidhannowe 2013-11-14 09:49:35

+0

爲了只獲得body標籤中的html,使用doc.at('body')。inner_html – 2014-11-03 13:33:11

+0

@Shanhannowe,這就是爲什麼該代碼使用'uri = URI.parse(src)',將字符串解析爲一個URI對象。 – 2014-11-03 17:54:08

0

顯然,這是與我經過搜索參數的問題,不要求轉義序列。

%r{<img src=\\('|")\/system\/images\/} 

簡單地變爲:

%r{<img src="/system/images/} 
1

難道你不能只使用'基'的HTML標籤來做到這一點?假設你直接從URL中讀取HTML內容,你可以這樣做:

response = RestClient.get(<original_url>) 
base_url = '<your_base_url>' 
html_content = response.body 
if html_content.index('<head>') 
    html_content = html_content.gsub!('<head>', "<head><base href='#{base_url}'>") 
end