2011-07-02 85 views
4

請使用正則表達式來幫助我從以下示例HTML中找到Favicon網址。它還應該檢查文件擴展名「.ico」。我正在開發個人書籤網站,我想保存我收藏的鏈接的圖標。我已經編寫了將圖標轉換爲gif並保存的c#代碼,但是我對正則表達式的知識非常有限,所以我無法選擇此標記,因爲結束標記在不同的站點中是不同的。結束標記 「/>」 「/鏈接>的實例」正則表達式從網頁中提取Favicon網址

我的編程語言是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

下一次,正確設置代碼的格式,以便人們有一點幫助你的機會。如果我們無法閱讀代碼,我們應該如何幫助您。您使用哪種語言來解析此內容?無論如何,不​​要使用正則表達式,使用HTML解析器。 –

+0

對不起。我該如何格式化代碼?我不明白。我在前面留下了4個空格,但我沒有看到它 – ziaasp

+0

@ziiee:[你沒有縮進那四行空格](http://stackoverflow.com/revisions/7cbc44d7-ebfa-4d95-a301-5513341ade5e/view -資源)。但即使如此,你只是發佈了一個長字符串,所以它最終會成爲一條線,這也是沒有用的。 –

回答

1

這應該與包含HREF = HTTP整個鏈路標籤://3dbin.com/favicon.ico

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

盤整爲主您的評論:

我看你有一個C#解決方案優秀!但是,如果你仍然想知道是否可以用正則表達式來完成,下面的表達式可以做你想要的。比賽的第一組只有url。

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

簡單的C#snipet,使得使用它:

// 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 
+0

我不想匹配整個標記。我上面提供的html只是一個示例。它可以根據網站 – ziaasp

+0

謝謝你。多數民衆贊成在我正在尋找 – ziaasp

+0

你是不受歡迎的。總是很樂意幫忙。 – Rob

1
<link\s+[^>]*(?:href\s*=\s*"([^"]+)"\s+)?rel\s*=\s*"shortcut icon"(?:\s+href\s*=\s*"([^"]+)")? 

也許......這是不穩健,但可以工作。 (我用的Perl的正則表達式)

+1

如果你把類型放在href之前和rel之後,它將不會工作......正如已經建議的那樣,更健壯的方法是通過一個html解析器...... – ShinTakezou

+0

謝謝,但我使用c#。 – ziaasp

+0

@ziiee:Perl和C#的正則表達式基本相同。 – Zano

1

這不是正則表達式的工作,因爲你看看你是否花了2分鐘在StackOverflow上尋找如何解析HTML。

Use an HTML parser instead!

下面是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

謝謝你,先生,這看起來比正則表達式更可讀。我會試試 – ziaasp

+0

不客氣。更可讀性等於更易於維護。更可維護更好! – Johnsyweb

+0

但您不是使用C#嗎? – ShinTakezou

1

我了個去,在這凌晨前陣子所以這裏這很簡單。首先它試圖找到/favicon.ico文件。如果失敗,我使用Html Agility pack加載頁面,然後使用xpath查找任何標籤。我通過鏈接標記來查看它們是否具有rel ='icon'屬性。如果他們這樣做,我抓住href屬性,並展開它,如果它存在該網站的絕對網址。

請隨時與此打交道,並提供任何改進。

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)); 
}