Regex для извлечения URL-адреса Favicon с веб-страницы - PullRequest
4 голосов
/ 02 июля 2011

Пожалуйста, помогите мне найти URL Favicon из примера HTML ниже, используя регулярное выражение. Следует также проверить расширение файла ".ico". Я занимаюсь разработкой личного сайта закладок и хочу сохранить избранные ссылки, которые я добавляю в закладки. Я уже написал код на c # для преобразования иконки в gif и сохранения, но у меня очень ограниченные знания о регулярных выражениях, поэтому я не могу выбрать этот тег, потому что конечные теги различаются на разных сайтах. Пример конечных тегов "/>" "/ link>"

Мой язык программирования - C #

<meta name="description" content="Create 360 degree rotation product presentation online with 3Dbin. 360 product pics, object rotationg presentation can be created for your website at 3DBin.com web service." />
<meta name="robots" content="index, follow" />
<meta name="verify-v1" content="x42ckCSDiernwyVbSdBDlxN0x9AgHmZz312zpWWtMf4=" />
<link rel="shortcut icon" href="http://3dbin.com/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="http://3dbin.com/css/1261391049/style.min.css" />
<!--[if lt IE 8]>
    <script src="http://3dbin.com/js/1261039165/IE8.js" type="text/javascript"></script>
<![endif]-->

решение: еще один способ сделать это Загрузите и добавьте ссылку на htmlagilitypack dll. Спасибо за помощь. Мне очень нравится этот сайт:)

 HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(readcontent);

    if (doc.DocumentNode != null)
    {
        foreach (HtmlNode link in doc.DocumentNode.SelectNodes(@"//link[@href]"))
        {

            HtmlAttribute att = link.Attributes["href"];
            if (att.Value.EndsWith(".ico"))
            {
                faviconurl = att.Value;
            }
        }
    }

Ответы [ 4 ]

1 голос
/ 06 июня 2012

Я попробовал это немного раньше, так что здесь есть кое-что довольно простое.Сначала он пытается найти файл /favicon.ico.Если это не удается, я загружаю страницу с помощью пакета Html Agility, а затем использую xpath, чтобы найти любые теги.Я перебираю теги ссылок, чтобы увидеть, имеют ли они атрибут rel = 'icon'.Если они это сделают, я возьму атрибут href и разверну его, если он существует, в абсолютный URL для этого сайта.

Пожалуйста, не стесняйтесь поиграть с этим и предложите любые улучшения.

private static Uri GetFaviconUrl(string siteUrl)
{
    // try looking for a /favicon.ico first
    var url = new Uri(siteUrl);
    var faviconUrl = new Uri(string.Format("{0}://{1}/favicon.ico", url.Scheme, url.Host));
    try
    {
        using (var httpWebResponse = WebRequest.Create(faviconUrl).GetResponse() as HttpWebResponse)
        {
            if (httpWebResponse != null && httpWebResponse.StatusCode == HttpStatusCode.OK)
            {
                // Log("Found a /favicon.ico file for {0}", url);
                return faviconUrl;
            }
        }
    }
    catch (WebException)
    {
    }

    // otherwise parse the html and look for <link rel='icon' href='' /> using html agility pack
    var htmlDocument = new HtmlWeb().Load(url.ToString());
    var links = htmlDocument.DocumentNode.SelectNodes("//link");
    if (links != null)
    {
        foreach (var linkTag in links)
        {
            var rel = GetAttr(linkTag, "rel");
            if (rel == null)
                continue;

            if (rel.Value.IndexOf("icon", StringComparison.InvariantCultureIgnoreCase) > 0)
            {
                var href = GetAttr(linkTag, "href");
                if (href == null)
                    continue;

                Uri absoluteUrl;
                if (Uri.TryCreate(href.Value, UriKind.Absolute, out absoluteUrl))
                {
                    // Log("Found an absolute favicon url {0}", absoluteUrl);
                    return absoluteUrl;
                }

                var expandedUrl = new Uri(string.Format("{0}://{1}{2}", url.Scheme, url.Host, href.Value));
                //Log("Found a relative favicon url for {0} and expanded it to {1}", url, expandedUrl);
                return expandedUrl;
            }
        }
    }

    // Log("Could not find a favicon for {0}", url);
    return null;
}

public static HtmlAttribute GetAttr(HtmlNode linkTag, string attr)
{
    return linkTag.Attributes.FirstOrDefault(x => x.Name.Equals(attr, StringComparison.InvariantCultureIgnoreCase));
}
1 голос
/ 02 июля 2011

Это должно соответствовать целому тегу ссылки, содержащему href = http://3dbin.com/favicon.ico

 <link .*? href="http://3dbin\.com/favicon\.ico" [^>]* />

Исправление на основе вашего комментария:

Я вижу, у вас есть решения на C # Отлично!Но на тот случай, если вам все еще интересно, можно ли это сделать с помощью регулярных выражений, следующее выражение будет делать то, что вы хотите.Группа 1 совпадения будет иметь только URL.

 <link .*? href="(.*?.ico)"

Простой фрагмент C #, использующий его:

// this is the snipet from your example with an extra link item in the form <link ... href="...ico" > ... </link> 
//just to make sure it would pick it up properly.
String htmlText = String htnlText = "<meta name=\"description\" content=\"Create 360 degree rotation product presentation online with 3Dbin. 360 product pics, object rotationg presentation can be created for your website at 3DBin.com web service.\" /><meta name=\"robots\" content=\"index, follow\" /><meta name=\"verify-v1\" content=\"x42ckCSDiernwyVbSdBDlxN0x9AgHmZz312zpWWtMf4=\" /><link rel=\"shortcut icon\" href=\"http://3dbin.com/favicon.ico\" type=\"image/x-icon\" /><link rel=\"shortcut icon\" href=\"http://anotherURL/someicofile.ico\" type=\"image/x-icon\">just to make sure it works with different link ending</link><link rel=\"stylesheet\" type=\"text/css\" href=\"http://3dbin.com/css/1261391049/style.min.css\" /><!--[if lt IE 8]>    <script src=\"http://3dbin.com/js/1261039165/IE8.js\" type=\"text/javascript\"></script><![endif]-->";

foreach (Match match in Regex.Matches(htmlText, "<link .*? href=\"(.*?.ico)\""))
{
    String url = match.Groups[1].Value;

    Console.WriteLine(url);
}

, который выводит на консоль следующее:

http://3dbin.com/favicon.ico
http://anotherURL/someicofile.ico
1 голос
/ 02 июля 2011

Это не работа для регулярного выражения, как вы увидите, если вы потратите 2 минуты на StackOverflow, ища, как разобрать HTML.

Вместо этого используйте HTML-анализатор!

Вот тривиальный пример в Python (я уверен, что это одинаково выполнимо в C #):

% python
Python 2.7.1 (r271:86832, May 16 2011, 19:49:41) 
[GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from BeautifulSoup import BeautifulSoup
>>> import urllib2
>>> page = urllib2.urlopen('https://stackoverflow.com/')
>>> soup = BeautifulSoup(page)
>>> link = soup.html.head.find(lambda x: x.name == 'link' and x['rel'] == 'shortcut icon')
>>> link['href']
u'http://cdn.sstatic.net/stackoverflow/img/favicon.ico'
>>> link['href'].endswith('.ico')
True
1 голос
/ 02 июля 2011
<link\s+[^>]*(?:href\s*=\s*"([^"]+)"\s+)?rel\s*=\s*"shortcut icon"(?:\s+href\s*=\s*"([^"]+)")?

возможно ... это не надежно, но может работать. (Я использовал регулярное выражение Perl)

...