2011-12-20 43 views
0

我正在使用bookmarklet,並且使用HTML DOM解析器(正如前面提出的SO答案)獲取任何外部頁面的所有照片。我正確地提取照片並在我的書籤彈出窗口中顯示。但是我遇到了照片相對路徑的問題。獲取外部網頁圖像的絕對路徑

例如外部頁面上的圖片來源說http://www.example.com/dir/index.php

  1. 圖片來源1:IMG源= '主機名/照片/ photo.jpg' - 獲取照片,因爲它是絕對

  2. 照片來源2:img source ='/ photos/photo.jpg' - 沒有得到,因爲它不是絕對的。

我通過當前網址工作我的意思是使用dirname或pathinfo獲取當前網址的目錄。但導致主機/目錄/(主機作爲父目錄)和主機/目錄/ index.php(主機/目錄作爲父目錄是正確的)之間的問題

請幫助我怎樣才能得到這些相對照片?

+0

那'link'呢?我的意思是'/photo/xdfa.jpg'只會從域名地址考慮。你也可以嘗試'./path/pics.jpg';它已經爲我工作 – Kris 2011-12-20 08:53:47

+0

那麼問題是什麼?如何檢測字符串是以'http://'還是'/'開頭? – Gordon 2011-12-20 08:56:36

回答

5

FIXED(增加了查詢字符串只圖像路徑的支持)

function make_absolute_path ($baseUrl, $relativePath) { 

    // Parse URLs, return FALSE on failure 
    if ((!$baseParts = parse_url($baseUrl)) || (!$pathParts = parse_url($relativePath))) { 
     return FALSE; 
    } 

    // Work-around for pre- 5.4.7 bug in parse_url() for relative protocols 
    if (empty($baseParts['host']) && !empty($baseParts['path']) && substr($baseParts['path'], 0, 2) === '//') { 
     $parts = explode('/', ltrim($baseParts['path'], '/')); 
     $baseParts['host'] = array_shift($parts); 
     $baseParts['path'] = '/'.implode('/', $parts); 
    } 
    if (empty($pathParts['host']) && !empty($pathParts['path']) && substr($pathParts['path'], 0, 2) === '//') { 
     $parts = explode('/', ltrim($pathParts['path'], '/')); 
     $pathParts['host'] = array_shift($parts); 
     $pathParts['path'] = '/'.implode('/', $parts); 
    } 

    // Relative path has a host component, just return it 
    if (!empty($pathParts['host'])) { 
     return $relativePath; 
    } 

    // Normalise base URL (fill in missing info) 
    // If base URL doesn't have a host component return error 
    if (empty($baseParts['host'])) { 
     return FALSE; 
    } 
    if (empty($baseParts['path'])) { 
     $baseParts['path'] = '/'; 
    } 
    if (empty($baseParts['scheme'])) { 
     $baseParts['scheme'] = 'http'; 
    } 

    // Start constructing return value 
    $result = $baseParts['scheme'].'://'; 

    // Add username/password if any 
    if (!empty($baseParts['user'])) { 
     $result .= $baseParts['user']; 
     if (!empty($baseParts['pass'])) { 
      $result .= ":{$baseParts['pass']}"; 
     } 
     $result .= '@'; 
    } 

    // Add host/port 
    $result .= !empty($baseParts['port']) ? "{$baseParts['host']}:{$baseParts['port']}" : $baseParts['host']; 

    // Inspect relative path path 
    if ($relativePath[0] === '/') { 

     // Leading/means from root 
     $result .= $relativePath; 

    } else if ($relativePath[0] === '?') { 

     // Leading ? means query the existing URL 
     $result .= $baseParts['path'].$relativePath; 

    } else { 

     // Get the current working directory 
     $resultPath = rtrim(substr($baseParts['path'], -1) === '/' ? trim($baseParts['path']) : str_replace('\\', '/', dirname(trim($baseParts['path']))), '/'); 

     // Split the image path into components and loop them 
     foreach (explode('/', $relativePath) as $pathComponent) { 
      switch ($pathComponent) { 
       case '': case '.': 
        // a single dot means "this directory" and can be skipped 
        // an empty space is a mistake on somebodies part, and can also be skipped 
        break; 
       case '..': 
        // a double dot means "up a directory" 
        $resultPath = rtrim(str_replace('\\', '/', dirname($resultPath)), '/'); 
        break; 
       default: 
        // anything else can be added to the path 
        $resultPath .= "/$pathComponent"; 
        break; 
      } 
     } 

     // Add path to result 
     $result .= $resultPath; 

    } 

    return $result; 

} 

測試:

echo make_absolute_path('http://www.example.com/dir/index.php','/photos/photo.jpg')."\n"; 
// Outputs: http://www.example.com/photos/photo.jpg 
echo make_absolute_path('http://www.example.com/dir/index.php','photos/photo.jpg')."\n"; 
// Outputs: http://www.example.com/dir/photos/photo.jpg 
echo make_absolute_path('http://www.example.com/dir/index.php','./photos/photo.jpg')."\n"; 
// Outputs: http://www.example.com/dir/photos/photo.jpg 
echo make_absolute_path('http://www.example.com/dir/index.php','../photos/photo.jpg')."\n"; 
// Outputs: http://www.example.com/photos/photo.jpg 
echo make_absolute_path('http://www.example.com/dir/index.php','http://www.yyy.com/photos/photo.jpg')."\n"; 
// Outputs: http://www.yyy.com/photos/photo.jpg 
echo make_absolute_path('http://www.example.com/dir/index.php','?query=something')."\n"; 
// Outputs: http://www.example.com/dir/index.php?query=something 

我認爲應該處理剛纔的一切你可能正確遭遇,和應該大致等同於瀏覽器所使用的邏輯。還應該糾正你在Windows上使用dirname()時可能會出現的雜散斜線。

第一個參數是在哪裏找到的<img>(或<a>或其他)的頁面,第二個參數的網址是src/href等屬性的內容。

如果有人發現一些不起作用的東西(因爲我知道你們都會試圖破壞它:-D),讓我知道,我會嘗試修復它。

+1

簡單的詞:AWESOMEE​​EEEE – Rohit 2011-12-20 09:38:55

+0

@Rohit我剛剛添加了幾個小修正:-) – DaveRandom 2011-12-20 09:49:46

0

'/'應該是基本路徑。檢查你的dom解析器返回的第一個字符,如果它是'/',那麼只需在域名前加前綴。

+0

好的,謝謝..請給我介紹一下這個案例,當主網站是像...... www.yahoo.com/news/....這樣的子目錄時,它會將www.yahoo.com作爲域名因此圖像路徑檢測將失敗。 – Rohit 2011-12-20 09:09:46

+0

通常,您應該始終使用完整的基本路徑+圖像路徑(如在您提供的#1示例中)。只有在img src以'/'開頭的情況下,您是否應該在第一個正斜槓之後使用完整路徑減號。所以www.yahoo.com/finance/AAPL => www.yahoo.com然後添加img src:'/photos/photo.jpg'。你的DOM解析器用什麼語言編寫的? – 2011-12-20 09:15:52