즐겨찾기 관리 프로그램이나 링크 모음 페이지를 만들다 보면 각 사이트 아이콘을 옆에 붙여 주고 싶어집니다. 아이콘 하나 받자고 사이트마다 소스 보기를 열어 <link rel="icon"> 경로를 찾는 건 꽤 번거롭죠. 이럴 때 구글이 제공하는 퍼비콘 주소를 쓰면 도메인만 바꿔 넣는 것으로 끝납니다.

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

<domain> 자리에 원하는 도메인을 넣으면 됩니다. 예를 들어 domain=naver.com 처럼 쓰고 브라우저 주소창에 붙여 넣으면 아이콘 이미지가 바로 뜨고, 다른 이름으로 저장하면 그대로 내려받아집니다. http://나 www. 는 붙이지 않아도 됩니다.

광고

그냥 /favicon.ico 로 받으면 안 되나

물론 사이트주소/favicon.ico 로 직접 받아도 되는 경우가 많습니다. 문제는 요즘 사이트 상당수가 아이콘을 루트에 두지 않고 별도 경로의 PNG나 SVG로 지정해 둔다는 점입니다. 이런 사이트는 /favicon.ico 를 요청하면 404가 나거나 엉뚱한 페이지가 돌아옵니다. 구글 쪽 주소는 그 사이트가 실제로 지정한 아이콘을 찾아서 돌려주기 때문에 실패하는 경우가 훨씬 적습니다.

주의할 점도 있습니다. 이름은 favicon이지만 돌려받는 파일은 보통 .ico 가 아니라 PNG 이미지입니다. 꼭 ico 형식이 필요하면 받은 뒤에 변환해야 합니다. 기본 크기는 16픽셀로 작은 편인데, 주소 뒤에 &sz=64 처럼 크기를 붙이면 더 큰 이미지를 받을 수 있습니다(사이트가 큰 아이콘을 갖고 있을 때만 선명하게 나옵니다). 그리고 구글이 공식 API로 문서화해 둔 기능은 아니어서, 상용 서비스의 핵심 기능을 여기에 전적으로 맡기는 건 피하는 게 좋습니다.

아이콘을 찾지 못한 사이트는 빈 응답 대신 기본 지구본 모양 아이콘이 돌아오는 경우가 많습니다. 목록 화면에 같은 지구본이 여러 개 보인다면 그 사이트들은 아이콘을 못 찾은 것이니, 필요하면 그 도메인만 /favicon.ico 로 한 번 더 시도해 보는 식으로 보완하면 됩니다.

프로그램에서 자동으로 저장하기

목록에 있는 도메인들의 아이콘을 한꺼번에 받아 두고 싶다면 코드로 돌리면 됩니다. VB.NET이라면 WebClient 하나로 충분합니다.

Imports System.Net

Module FaviconDownloader
    Sub SaveFavicon(domain As String, savePath As String)
        Dim url As String = "http://www.google.com/s2/favicons?domain=" & domain
        Using wc As New WebClient()
            wc.DownloadFile(url, savePath)
        End Using
    End Sub

    Sub Main()
        SaveFavicon("naver.com", "C:\Temp\naver.png")
    End Sub
End Module

저장 확장자를 .png 로 준 것은 위에서 말한 것처럼 실제 내용이 PNG이기 때문입니다. 도메인이 많다면 매번 받지 말고 한 번 받은 파일을 로컬에 캐시해 두는 편이 좋습니다. 아이콘은 거의 바뀌지 않는 데다, 같은 주소를 짧은 시간에 반복해서 요청하면 차단될 수도 있으니까요. 웹 페이지라면 <img> 태그의 src에 이 주소를 그대로 넣어 쓰는 방법도 있지만, 매번 외부 요청이 생기므로 방문자가 많은 페이지라면 서버에 저장해 두고 쓰는 쪽을 권합니다.

여러 도메인을 돌릴 때 걸리는 부분

위 SaveFavicon을 목록에 대해 반복 호출하면 되는데, 실제로 돌리면 몇 가지에서 막힙니다. 하나는 예외입니다. 주소가 잘못됐거나 네트워크가 잠깐 끊기면 DownloadFile이 WebException을 던지고, 반복문 전체가 멈춥니다. 도메인 하나가 실패해도 다음으로 넘어가도록 호출부를 Try로 감싸 두세요.

For Each d As String In {"naver.com", "daum.net", "google.com"}
    Try
        SaveFavicon(d, IO.Path.Combine("C:\Temp", d & ".png"))
    Catch ex As WebException
        Console.WriteLine(d & " 실패: " & ex.Message)
    End Try
Next

또 하나는 파일 이름입니다. 도메인을 그대로 파일 이름으로 쓰면 편하지만 localhost:8080처럼 포트가 붙은 주소는 콜론 때문에 윈도우 파일 이름이 될 수 없습니다. 이런 값이 섞일 수 있다면 콜론을 밑줄로 바꾸는 정도의 정리를 해 두면 됩니다. 저장 폴더(C:\Temp)가 없으면 역시 예외가 나니 시작할 때 IO.Directory.CreateDirectory로 만들어 두고요. .NET Framework 4.x에서 https 주소로 바꿔 받다가 연결이 안 된다면 ServicePointManager.SecurityProtocol에 TLS 1.2를 지정해 보는 것도 잊지 마세요.