web-dev-qa-db-ja.com

PHPでウェブサイトのファビコンを取得するにはどうすればよいですか?

リクエストしたウェブサイトのファビコンをPHPで取得したい。 Googleのファビコンサービスの使用をお勧めしますが、機能しません。自分で何かしたいのですが、正規表現の使い方がわかりません。

ほとんどの場合に機能するクラスをGoogleで見つけましたが、許容できないエラー率があります。ここで見ることができます: http://www.controlstyle.com/articles/programming/text/php-favicon/

誰かが正規表現を使用してファビコンを取得するのを手伝ってくれませんか?

17
Kemal

PHPグラブファビコン

これは、ページのURLからファビコンを取得するための多くのパラメーターを使用する快適な方法です。

使い方

  1. ファビコンがすでにローカルに存在するかどうか、または保存を希望しないかどうかを確認します。存在する場合は、パスとファイル名を返します。
  2. それ以外の場合はURLをロードし、ファビコンの場所を正規表現と一致させてみてください
  3. 一致する場合、ファビコンリンクは絶対になります
  4. ファビコンがない場合は、ドメインルートでファビコンを取得しようとします
  5. それでもファビコンがない場合は、Google、ファビコンキット、ファビコングラバーAPIをランダムに試します
  6. ファビコンを保存する必要がある場合は、ファビコンURLをロードしてみてください
  7. 必要に応じて、次回のためにファビコンを保存し、パスとファイル名を返します

したがって、両方の方法を組み合わせます。ページからファビコンを取得してみてください。それが機能しない場合は、ファビコンを返す「API」サービスを使用してください;-)

<?php
/*

PHP Grab Favicon
================

> This `PHP Favicon Grabber` use a given url, save a copy (if wished) and return the image path.

How it Works
------------

1. Check if the favicon already exists local or no save is wished, if so return path & filename
2. Else load URL and try to match the favicon location with regex
3. If we have a match the favicon link will be made absolute
4. If we have no favicon we try to get one in domain root
5. If there is still no favicon we randomly try google, faviconkit & favicongrabber API
6. If favicon should be saved try to load the favicon URL
7. If wished save the Favicon for the next time and return the path & filename

How to Use
----------

```PHP
$url = 'example.com';

$grap_favicon = array(
'URL' => $url,   // URL of the Page we like to get the Favicon from
'SAVE'=> true,   // Save Favicon copy local (true) or return only favicon url (false)
'DIR' => './',   // Local Dir the copy of the Favicon should be saved
'TRY' => true,   // Try to get the Favicon frome the page (true) or only use the APIs (false)
'DEV' => null,   // Give all Debug-Messages ('debug') or only make the work (null)
);

echo '<img src="'.grap_favicon($grap_favicon).'">';
```

Todo
----
Optional split the download dir into several sub-dirs (MD5 segment of filename e.g. /af/cd/example.com.png) if there are a lot of favicons.

Infos about Favicon
-------------------
https://github.com/audreyr/favicon-cheat-sheet

###### Copyright 2019 Igor Gaffling

*/ 

$testURLs = array(
  'http://aws.Amazon.com',
  'http://www.Apple.com',
  'http://www.dribbble.com',
  'http://www.github.com',
  'http://www.intercom.com',
  'http://www.indiehackers.com',
  'http://www.medium.com',
  'http://www.mailchimp.com',
  'http://www.netflix.com',
  'http://www.producthunt.com',
  'http://www.reddit.com',
  'http://www.slack.com',
  'http://www.soundcloud.com',
  'http://www.stackoverflow.com',
  'http://www.techcrunch.com',
  'http://www.trello.com',
  'http://www.vimeo.com',
  'https://www.whatsapp.com/',
  'https://www.gaffling.com/',
);

foreach ($testURLs as $url) {
  $grap_favicon = array(
    'URL' => $url,   // URL of the Page we like to get the Favicon from
    'SAVE'=> true,   // Save Favicon copy local (true) or return only favicon url (false)
    'DIR' => './',   // Local Dir the copy of the Favicon should be saved
    'TRY' => true,   // Try to get the Favicon frome the page (true) or only use the APIs (false)
    'DEV' => null,   // Give all Debug-Messages ('debug') or only make the work (null)
  );
  $favicons[] = grap_favicon($grap_favicon);
}
foreach ($favicons as $favicon) {
  echo '<img title="'.$favicon.'" style="width:32px;padding-right:32px;" src="'.$favicon.'">';
}
echo '<br><br><tt>Runtime: '.round((microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]),2).' Sec.';

function grap_favicon( $options=array() ) {

  // Ini Vars
  $url       = (isset($options['URL']))?$options['URL']:'gaffling.com';
  $save      = (isset($options['SAVE']))?$options['SAVE']:true;
  $directory = (isset($options['DIR']))?$options['DIR']:'./';
  $trySelf   = (isset($options['TRY']))?$options['TRY']:true;
  $DEBUG     = (isset($options['DEV']))?$options['DEV']:null;

  // URL to lower case
    $url = strtolower($url);

    // Get the Domain from the URL
  $domain = parse_url($url, PHP_URL_Host);

  // Check Domain
  $domainParts = explode('.', $domain);
  if(count($domainParts) == 3 and $domainParts[0]!='www') {
    // With Subdomain (if not www)
    $domain = $domainParts[0].'.'.
              $domainParts[count($domainParts)-2].'.'.$domainParts[count($domainParts)-1];
  } else if (count($domainParts) >= 2) {
    // Without Subdomain
        $domain = $domainParts[count($domainParts)-2].'.'.$domainParts[count($domainParts)-1];
    } else {
      // Without http(s)
      $domain = $url;
    }

    // FOR DEBUG ONLY
    if($DEBUG=='debug')print('<b style="color:red;">Domain</b> #'.@$domain.'#<br>');

    // Make Path & Filename
    $filePath = preg_replace('#\/\/#', '/', $directory.'/'.$domain.'.png');

    // If Favicon not already exists local
  if ( !file_exists($filePath) or @filesize($filePath)==0 ) {

    // If $trySelf == TRUE ONLY USE APIs
    if ( isset($trySelf) and $trySelf == TRUE ) {  

      // Load Page
      $html = load($url, $DEBUG);

      // Find Favicon with RegEx
      $regExPattern = '/((<link[^>]+rel=.(icon|shortcut icon|alternate icon)[^>]+>))/i';
      if ( @preg_match($regExPattern, $html, $matchTag) ) {
        $regExPattern = '/href=(\'|\")(.*?)\1/i';
        if ( isset($matchTag[1]) and @preg_match($regExPattern, $matchTag[1], $matchUrl)) {
          if ( isset($matchUrl[2]) ) {

            // Build Favicon Link
            $favicon = rel2abs(trim($matchUrl[2]), 'http://'.$domain.'/');

            // FOR DEBUG ONLY
            if($DEBUG=='debug')print('<b style="color:red;">Match</b> #'.@$favicon.'#<br>');

          }
        }
      }

      // If there is no Match: Try if there is a Favicon in the Root of the Domain
        if ( empty($favicon) ) { 
        $favicon = 'http://'.$domain.'/favicon.ico';

        // Try to Load Favicon
        if ( !@getimagesize($favicon) ) {
          unset($favicon);
        }
        }

    } // END If $trySelf == TRUE ONLY USE APIs

    // If nothink works: Get the Favicon from API
    if ( !isset($favicon) or empty($favicon) ) {

      // Select API by Random
      $random = Rand(1,3);

      // Faviconkit API
      if ($random == 1 or empty($favicon)) {
        $favicon = 'https://api.faviconkit.com/'.$domain.'/16';
      }

      // Favicongrabber API
      if ($random == 2 or empty($favicon)) {
        $echo = json_decode(load('http://favicongrabber.com/api/grab/'.$domain,FALSE),TRUE);

        // Get Favicon URL from Array out of json data (@ if something went wrong)
        $favicon = @$echo['icons']['0']['src'];

      }

      // Google API (check also md5() later)
      if ($random == 3) {
        $favicon = 'http://www.google.com/s2/favicons?domain='.$domain;
      } 

      // FOR DEBUG ONLY
      if($DEBUG=='debug')print('<b style="color:red;">'.$random.'. API</b> #'.@$favicon.'#<br>');

    } // END If nothink works: Get the Favicon from API

    // Write Favicon local
    $filePath = preg_replace('#\/\/#', '/', $directory.'/'.$domain.'.png');

    // If Favicon should be saved
    if ( isset($save) and $save == TRUE ) {

      //  Load Favicon
      $content = load($favicon, $DEBUG);

      // If Google API don't know and deliver a default Favicon (World)
      if ( isset($random) and $random == 3 and 
           md5($content) == '3ca64f83fdcf25135d87e08af65e68c9' ) {
        $domain = 'default'; // so we don't save a default icon for every domain again

        // FOR DEBUG ONLY
        if($DEBUG=='debug')print('<b style="color:red;">Google</b> #use default icon#<br>');

      }

      // Write 
      $fh = @fopen($filePath, 'wb');
      fwrite($fh, $content);
      fclose($fh);

      // FOR DEBUG ONLY
        if($DEBUG=='debug')print('<b style="color:red;">Write-File</b> #'.@$filePath.'#<br>');

    } else {

      // Don't save Favicon local, only return Favicon URL
      $filePath = $favicon;
    }

    } // END If Favicon not already exists local

    // FOR DEBUG ONLY
    if ($DEBUG=='debug') {

    // Load the Favicon from local file
      if ( !function_exists('file_get_contents') ) {
      $fh = @fopen($filePath, 'r');
      while (!feof($fh)) {
        $content .= fread($fh, 128); // Because filesize() will not work on URLS?
      }
      fclose($fh);
    } else {
      $content = file_get_contents($filePath);
    }
      print('<b style="color:red;">Image</b> <img style="width:32px;" 
             src="data:image/png;base64,'.base64_encode($content).'"><hr size="1">');
  }

  // Return Favicon Url
  return $filePath;

} // END MAIN Function

/* HELPER load use curl or file_get_contents (both with user_agent) and fopen/fread as fallback */
function load($url, $DEBUG) {
  if ( function_exists('curl_version') ) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_USERAGENT, 'FaviconBot/1.0 (+http://'.$_SERVER['SERVER_NAME'].'/');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    $content = curl_exec($ch);
    if ( $DEBUG=='debug' ) { // FOR DEBUG ONLY
      $http_code = curl_getinfo($ch);
      print('<b style="color:red;">cURL</b> #'.$http_code['http_code'].'#<br>');
    }
    curl_close($ch);
    unset($ch);
  } else {
    $context = array ( 'http' => array (
        'user_agent' => 'FaviconBot/1.0 (+http://'.$_SERVER['SERVER_NAME'].'/)'),
    );
    $context = stream_context_create($context);
      if ( !function_exists('file_get_contents') ) {
      $fh = fopen($url, 'r', FALSE, $context);
      $content = '';
      while (!feof($fh)) {
        $content .= fread($fh, 128); // Because filesize() will not work on URLS?
      }
      fclose($fh);
    } else {
      $content = file_get_contents($url, NULL, $context);
    }
  }
  return $content;
}

/* HELPER: Change URL from relative to absolute */
function rel2abs( $rel, $base ) {
    extract( parse_url( $base ) );
    if ( strpos( $rel,"//" ) === 0 ) return $scheme . ':' . $rel;
    if ( parse_url( $rel, PHP_URL_SCHEME ) != '' ) return $rel;
    if ( $rel[0] == '#' or $rel[0] == '?' ) return $base . $rel;
    $path = preg_replace( '#/[^/]*$#', '', $path);
    if ( $rel[0] ==  '/' ) $path = '';
    $abs = $Host . $path . "/" . $rel;
    $abs = preg_replace( "/(\/\.?\/)/", "/", $abs);
    $abs = preg_replace( "/\/(?!\.\.)[^\/]+\/\.\.\//", "/", $abs);
    return $scheme . '://' . $abs;
}

ソース: https://github.com/gaffling/PHP-Grab-Favicon

0
adilbo

使用 S2 servicegoogleによって提供されます。これと同じくらい簡単です

http://www.google.com/s2/favicons?domain=www.yourdomain.com

これをこすることは、自分でやろうとするよりもはるかに簡単です。

46
Starx

速くて汚い:

<?php 
$url = 'http://example.com/';
$doc = new DOMDocument();
$doc->strictErrorChecking = FALSE;
$doc->loadHTML(file_get_contents($url));
$xml = simplexml_import_dom($doc);
$arr = $xml->xpath('//link[@rel="shortcut icon"]');
echo $arr[0]['href'];
32
vooD

http://www.getfavicon.org/?url=domain.com[〜#〜] faq [〜#〜] )がWebサイトのファビコンを確実にスクレイプしているようです。サードパーティのサービスだと思いますが、Googleのファビコンサービスに代わる価値のあるサービスだと思います。

4
Marcel

私は似たようなことをしてきましたが、これをたくさんのURLで確認したところ、すべてうまくいったようです。 RLはベースURLである必要はありません

function getFavicon($url){
    # make the URL simpler
    $elems = parse_url($url);
    $url = $elems['scheme'].'://'.$elems['Host'];

    # load site
    $output = file_get_contents($url);

    # look for the shortcut icon inside the loaded page
    $regex_pattern = "/rel=\"shortcut icon\" (?:href=[\'\"]([^\'\"]+)[\'\"])?/";
    preg_match_all($regex_pattern, $output, $matches);

    if(isset($matches[1][0])){
        $favicon = $matches[1][0];

        # check if absolute url or relative path
        $favicon_elems = parse_url($favicon);

        # if relative
        if(!isset($favicon_elems['Host'])){
            $favicon = $url . '/' . $favicon;
        }

        return $favicon;
    }

    return false;
}
3
blackpla9ue

ウィキペディア によると、ブラウザでファビコンを取得するためにWebサイトで使用できる2つの主要な方法があります。 1つ目は、Steveが述べたように、アイコンをfavicon.icoとしてWebサーバーのルートディレクトリに保存します。 2つ目は、HTMLリンクタグを介してファビコンを参照することです。

これらすべてのケースをカバーするには、最初にfavicon.icoファイルの存在をテストし、存在しない場合は、で<link rel="icon"または<link rel="shortcut icon"のいずれかの部分を検索することをお勧めします。ファビコンが見つかるまでソース(HTMLヘッドノードに限定)。正規表現を使用するか、 他の文字列検索オプション を使用するかはあなた次第です(組み込みのPHPは言うまでもありません)。 1つ)。最後に、 この質問 はあなたの助けになるかもしれません。

3
mdec

見つかった場合はfavicon.icoから検索でき、それ以外の場合は表示されない最初の方法

<?php
        $userPath=$_POST["url"];
        $path="http://www.".$userPath."/favicon.ico";
        $header=  get_headers($path);
        if(preg_match("|200|", $header[0]))
        {
            echo '<img src="'.$path.'">';
        }
        else
        {
            echo "<span class=error>Not found</span>";
        }
    ?>

他の方法では、アイコンを検索してそのアイコンファイルを取得できます

    <?php
$website=$_POST["url"];
$fevicon= getFavicon($website);
echo '<img src="http://www.'.$website.'/'.$fevicon.'">';
function getFavicon($site)
{
            $html=file_get_contents("http://www.".$site);
            $dom=new DOMDocument();
            @$dom->loadHTML($html);
            $links=$dom->getElementsByTagName('link');
            $fevicon='';

            for($i=0;$i < $links->length;$i++ )
            {
                $link=$links->item($i);
                if($link->getAttribute('rel')=='icon'||$link->getAttribute('rel')=="Shortcut Icon"||$link->getAttribute('rel')=="shortcut icon")
                {
                    $fevicon=$link->getAttribute('href');
                }
            }
            return  $fevicon;
}
?>
2
Vivek

私は自分のファビコングラバーを実装しました、そして私はここで別のStackOverflow投稿で使用法を詳述しました: JSでウェブサイトのファビコンを取得してください

ありがとう、そしてそれがあなたを助けるかどうか私に知らせてください。また、フィードバックは大歓迎です。

2
Jaime Bellmyer

この答えを参照してください: https://stackoverflow.com/a/22771267 。 PHPクラスを使用してファビコンURLを取得してダウンロードするのは簡単です。また、ファイルタイプやファビコンの検出方法(デフォルトURL、<link>タグ...):

<?php
require 'FaviconDownloader.class.php';
$favicon = new FaviconDownloader('https://code.google.com/p/chromium/issues/detail?id=236848');

if($favicon->icoExists){
    echo "Favicon found : ".$favicon->icoUrl."\n";

    // Saving favicon to file
    $filename = 'favicon-'.time().'.'.$favicon->icoType;
    file_put_contents($filename, $favicon->icoData);
    echo "Saved to ".$filename."\n\n";
} else {
    echo "No favicon for ".$favicon->url."\n\n";
}

$favicon->debug();
/*
FaviconDownloader Object
(
    [url] => https://code.google.com/p/chromium/issues/detail?id=236848
    [pageUrl] => https://code.google.com/p/chromium/issues/detail?id=236848
    [siteUrl] => https://code.google.com/
    [icoUrl] => https://ssl.gstatic.com/codesite/ph/images/phosting.ico
    [icoType] => ico
    [findMethod] => head absolue_full
    [error] => 
    [icoExists] => 1
    [icoMd5] => a6cd47e00e3acbddd2e8a760dfe64cdc
)
*/
?>
1
Vince

特定のWebサイトからファビコンを取得する場合は、Webサイトのルートからfavicon.icoを取得するだけです。そのようです:

$domain = "www.example.com";
$url = "http://".$domain."/favicon.ico";
$icondata = file_get_contents($url);

... you can now do what you like with the icon data
0
Steve Mayne

このスレッドを見つけました...ファビコンの取得に関する多くのバリエーションを含むWordPressプラグインを作成しました。GPLコードがたくさんあるので: http:// plugins .svn.wordpress.org/wp-favicons/trunk /

これにより、xml rpcリクエストを介してアイコンをリクエストできるサーバーを実行できるため、すべてのクライアントがアイコンをリクエストできます。プラグイン構造を持っているので、google、getfaviconなどを試して、これらのサービスの1つが何かを提供するかどうかを確認できます。そうでない場合は、すべてのhttpステータス(301/302/404)を考慮してアイコンフェッチモードに入り、どこにでもアイコンを見つけるのが最善です。この後、画像ライブラリ関数を使用して、ファイルが本当に画像であるかどうか、どのような種類の画像(拡張子が間違っている場合もある)かをチェックし、プラグイン可能であるため、画像変換またはパイプラインの追加機能の後に追加できます。

httpフェッチファイルは、私が上で見たものの周りにいくつかのロジックを実行します: http://plugins.svn.wordpress.org/wp-favicons/trunk/includes/server/class-http.php

しかし、それはパイプラインの一部にすぎません。

あなたがそれに飛び込むとかなり複雑になる可能性があります。

0
edelwater
$url = 'http://thamaraiselvam.strikingly.com/';
$doc = new DOMDocument();
$doc->strictErrorChecking = FALSE;
@$doc->loadHTML(file_get_contents($url));
$xml = simplexml_import_dom($doc);
$arr = $xml->xpath('//link[@rel="shortcut icon"]');
if (!empty($arr[0]['href'])) {
    echo "<img src=".$arr[0]['href'].">";
 }
else 
echo "<img src='".$url."/favicon.ico'>";
0
Thamaraiselvam

私は少し変更しました Vivekの2番目の方法 そして この関数 を追加しました、そしてそれはこのように見えます:

<?php
        $website=$_GET['u'];
        $fevicon= getFavicon($website);
        echo '<img src="'.path_to_absolute($fevicon,$website).'"></img>';

            function getFavicon($site)
            {
            $html=file_get_contents($site);
            $dom=new DOMDocument();
            @$dom->loadHTML($html);
            $links=$dom->getElementsByTagName('link');
            $fevicon='';

            for($i=0;$i < $links->length;$i++ )
            {
                $link=$links->item($i);
                if($link->getAttribute('rel')=='icon'||$link->getAttribute('rel')=="Shortcut Icon"||$link->getAttribute('rel')=="shortcut icon")
                {
                    $fevicon=$link->getAttribute('href');
                }
            }
            return  $fevicon;
            }

    // transform to absolute path function... 
    function path_to_absolute($rel, $base)
    {
    /* return if already absolute URL */
    if (parse_url($rel, PHP_URL_SCHEME) != '') return $rel;
    /* queries and anchors */
    if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel;
    /* parse base URL and convert to local variables:
       $scheme, $Host, $path */
    extract(parse_url($base));
    /* remove non-directory element from path */
    $path = preg_replace('#/[^/]*$#', '', $path);
    /* destroy path if relative url points to root */
    if ($rel[0] == '/') $path = '';
    /* dirty absolute URL */
    $abs = "$Host$path/$rel";
    /* replace '//' or '/./' or '/foo/../' with '/' */
    $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
    for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
    /* absolute URL is ready! */
    return $scheme.'://'.$abs;
    }

?>

もちろん、https://www.domain.tld/favicon/this_script.php?u=http://www.example.comで呼び出します。それでもすべてのオプションをキャッチすることはできませんが、絶対パスが解決されます。それが役に立てば幸い。

0
pc_