C#通過正則表達(dá)式實(shí)現(xiàn)提取網(wǎng)頁中的圖片
目前在做項(xiàng)目中有處理圖片的部分,參考了一下網(wǎng)上案例,自己寫了一個(gè)獲取內(nèi)容中的圖片地址的方法。
一般來說一個(gè) HTML 文檔有很多標(biāo)簽,比如“<html>”、“<body>”、“<table>”等,想把文檔中的 img 標(biāo)簽提取出來并不是一件容易的事。由于 img 標(biāo)簽樣式變化多端,使提取的時(shí)候用程序?qū)ふ也⒉蝗菀?。于是想要尋找它們就必須寫一個(gè)非常健全的正則表達(dá)式,不然有可能會找得不全,或者找出來的不是正確的 img 標(biāo)簽。
我們可以從 HTML 標(biāo)簽的格式去想應(yīng)該怎么建這個(gè)正則表達(dá)式。首先要想一下 img 標(biāo)簽有幾種寫法,忽略大小寫不看的話,下面列出 img 標(biāo)簽可能出現(xiàn)的幾種情況。
<img> <img/> <img src=/>
這一些標(biāo)簽不用考慮,因?yàn)闆]有圖片資源地址。
<img src = /images/pic.jpg/ > <img src =" /images/pic.jpg" > <img src= '/images/pic.jpg ' / >
這一些標(biāo)簽都有圖片資源地址,另外還有一個(gè)特點(diǎn)就是有引號對,可能為單引號,也可能為雙引號。因?yàn)椴恍枰瑫r(shí)匹配引號對,所以正則表達(dá)式可以這么寫:@"<img\s*src\s*=\s*[""']?\s*(?[^\s""'<>]*)\s*/?\s*>"
<img width="320" height="240" src=/images/pic.jpg onclick="window.open('/images/pic.jpg')">
因?yàn)?img 和 src 之間可能會有其他的參數(shù),所以“<img”要有個(gè)單詞結(jié)束,比如說不能是“<imgabc”,同樣 src 前面也是一樣,使用單詞結(jié)束符“\b”有一個(gè)好處就是省去了表示空格的“\s*”。另外由于 img 標(biāo)簽中不可以出現(xiàn)“<”、“>”這樣的符號,所以要改寫前面的正則表達(dá)式:@"<img\b[^<>]*?\bsrc\s*=\s*[""']?\s*(?<imgUrl>[^\s""'<>]*)[^<>]*?/?\s*>"
<img width="320" height="240" src = "
/images/pic.jpg" />
像這種可能會用回車符折行的問題有時(shí)候會出現(xiàn),所以在有空格分開的地方要包含回車換行和 TAB 字符,另外在圖片地址中不能出現(xiàn)空格、TAB、回車和換行字符。
所以上面的正則表達(dá)式可以改成:@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>"
下面寫出取得HTML中所有圖片地址的類HvtHtmlImage:
using System.Text.RegularExpressions; namespace HoverTree.HoverTreeFrame.HvtImage { public class HvtHtmlImage { /// <summary> /// 取得HTML中所有圖片的 URL。 /// </summary> /// <param name="sHtmlText">HTML代碼</param> /// <returns>圖片的URL列表</returns> public static string[] GetHvtImgUrls(string sHtmlText) { // 定義正則表達(dá)式用來匹配 img 標(biāo)簽 Regex m_hvtRegImg = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase); // 搜索匹配的字符串 MatchCollection matches = m_hvtRegImg.Matches(sHtmlText); int m_i = 0; string[] sUrlList = new string[matches.Count]; // 取得匹配項(xiàng)列表 foreach (Match match in matches) sUrlList[m_i++] = match.Groups["imgUrl"].Value; return sUrlList; } } }
下面我們再來看一個(gè)例子
public Array MatchHtml(string html,string com) { List<string> urls = new List<string>(); html = html.ToLower(); //獲取SRC標(biāo)簽中的URL Regex regexSrc = new Regex("src=\"[^\"]*[(.jpg)(.png)(.gif)(.bmp)(.ico)]\""); foreach(Match m in regexSrc.Matches(html)) { string src = m.Value; src = src.Replace("src=","").Replace("\"",""); if (!src.Contains("http")) src = com + src; if(!urls.Contains(src)) urls.Add(src); } //獲取HREF標(biāo)簽中URL Regex regexHref = new Regex("href=\"[^\"]*[(.jpg)(.png)(.gif)(.bmp)(.ico)]\""); foreach (Match m in regexHref.Matches(html)) { string href = m.Value; href = href.Replace("href=", "").Replace("\"", ""); if (!href.Contains("http")) href = com + href; if(!urls.Contains(href)) urls.Add(href); } return urls.ToArray(); }
[DllImport("kernel32.dll")] static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode); [DllImport("kernel32.dll")] static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int mode); [DllImport("kernel32.dll")] static extern IntPtr GetStdHandle(int handle); const int STD_INPUT_HANDLE = -10; const int ENABLE_QUICK_EDIT_MODE = 0x40 | 0x80; public static void EnableQuickEditMode() { int mode; IntPtr handle = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(handle, out mode); mode |= ENABLE_QUICK_EDIT_MODE; SetConsoleMode(handle, mode); } static void Main(string[] args) { EnableQuickEditMode(); int oldCount = 0; Console.Title = "TakeImageFromInternet"; string path = "E:\\Download\\loading\\"; while (true) { Console.Clear(); string countFile = "E:\\CountFile.txt";//用來計(jì)數(shù)的文本,以至于文件名不重復(fù) int cursor = 0; if (File.Exists(countFile)) { string text = File.ReadAllText(countFile); try { cursor =oldCount = Convert.ToInt32(text);//次數(shù)多了建議使用long } catch { } } Console.Write("please input a url:"); string url = "http://www.baidu.com/"; string temp = Console.ReadLine(); if (!string.IsNullOrEmpty(temp)) url = temp; Match mcom = new Regex(@"^(?i)http://(\w+\.){2,3}(com(\.cn)?|cn|net)\b").Match(url);//獲取域名 string com = mcom.Value; //Console.WriteLine(mcom.Value); Console.Write("please input a save path:"); temp = Console.ReadLine(); if (Directory.Exists(temp)) path = temp; Console.WriteLine(); WebClient client = new WebClient(); byte[] htmlData = null; htmlData = client.DownloadData(url); MemoryStream mstream = new MemoryStream(htmlData); string html = ""; using (StreamReader sr = new StreamReader(mstream)) { html = sr.ReadToEnd(); } Array urls = new MatchHtmlImageUrl().MatchHtml(html,com); foreach (string imageurl in urls) { Console.WriteLine(imageurl); byte[] imageData = null; try { imageData = client.DownloadData(imageurl); } catch { } if (imageData != null && imageData.Length>0) using (MemoryStream ms = new MemoryStream(imageData)) { try { string ext = Aping.Utility.File.FileOpration.ExtendName(imageurl); ImageFormat format = ImageFormat.Jpeg; switch (ext) { case ".jpg": format = ImageFormat.Jpeg; break; case ".bmp": format = ImageFormat.Bmp; break; case ".png": format = ImageFormat.Png; break; case ".gif": format = ImageFormat.Gif; break; case ".ico": format = ImageFormat.Icon; break; default: continue; } Image image = new Bitmap(ms); if (Directory.Exists(path)) image.Save(path + "\\" + cursor + ext, format); } catch(Exception ex) { Console.WriteLine(ex.Message); } } cursor++; } mstream.Close(); File.WriteAllText(countFile, cursor.ToString(), Encoding.UTF8); Console.WriteLine("take done...image count:"+(cursor-oldCount).ToString()); } }
上一篇:C#操作注冊表的方法詳解
欄 目:C#教程
下一篇:C#創(chuàng)建數(shù)據(jù)庫及導(dǎo)入sql腳本的方法
本文標(biāo)題:C#通過正則表達(dá)式實(shí)現(xiàn)提取網(wǎng)頁中的圖片
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/6786.html
您可能感興趣的文章
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并打開的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的方法
- 01-10C#通過Semaphore類控制線程隊(duì)列的方法
- 01-10C#編程自學(xué)之運(yùn)算符和表達(dá)式
- 01-10C#正則表達(dá)式的6個(gè)簡單例子
- 01-10C#中的正則表達(dá)式介紹
- 01-10C#使用正則表達(dá)式實(shí)現(xiàn)首字母轉(zhuǎn)大寫的方法
- 01-10輕松學(xué)習(xí)C#的正則表達(dá)式
- 01-10詳解C#正則表達(dá)式Regex常用匹配
- 01-10C#正則表達(dá)式Regex類的常用匹配


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 08-05織夢dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢data目錄下的sessions文件夾有什