Как проанализировать HTML-строку на наличие тегов изображений, чтобы получить информацию SRC?
Вопрос
В настоящее время я использую .Net WebBrowser.Document.Images()
сделать это.Это требует Webrowser
чтобы загрузить документ.Это грязно и отнимает ресурсы.
В соответствии с этот вопрос XPath в этом отношении лучше, чем регулярное выражение.
Кто-нибудь знает, как это сделать на C#?
Решение
Если ваша входная строка является допустимым XHTML, вы можете обработать ее как xml, загрузить ее в xml-документ и творить чудеса XPath :) Но это не всегда так.
В противном случае вы можете попробовать эту функцию, которая вернет все ссылки на изображения из HtmlSource:
public List<Uri> FetchLinksFromSource(string htmlSource)
{
List<Uri> links = new List<Uri>();
string regexImgSrc = @"<img[^>]*?src\s*=\s*[""']?([^'"" >]+?)[ '""][^>]*?>";
MatchCollection matchesImgSrc = Regex.Matches(htmlSource, regexImgSrc, RegexOptions.IgnoreCase | RegexOptions.Singleline);
foreach (Match m in matchesImgSrc)
{
string href = m.Groups[1].Value;
links.Add(new Uri(href));
}
return links;
}
И вы можете использовать его так:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.example.com");
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
using(StreamReader sr = new StreamReader(response.GetResponseStream()))
{
List<Uri> links = FetchLinksFromSource(sr.ReadToEnd());
}
}
Другие советы
Большой проблемой при любом анализе HTML является «правильно сформированная» часть.Вы видели этот дерьмовый HTML — насколько он действительно хорошо сформирован?Мне нужно было сделать что-то подобное — разобрать все ссылки в документе (и в моем случае обновить их переписанной ссылкой).Я нашел HTML-пакет гибкости на CodePlex.Он потрясающий (и обрабатывает неверный HTML).
Вот фрагмент для перебора ссылок в документе:
HtmlDocument doc = new HtmlDocument();
doc.Load(@"C:\Sample.HTM");
HtmlNodeCollection linkNodes = doc.DocumentNode.SelectNodes("//a/@href");
Content match = null;
// Run only if there are links in the document.
if (linkNodes != null)
{
foreach (HtmlNode linkNode in linkNodes)
{
HtmlAttribute attrib = linkNode.Attributes["href"];
// Do whatever else you need here
}
}
Если все, что вам нужно, это изображения, я бы просто использовал регулярное выражение.Что-то вроде этого должно помочь:
Regex rg = new Regex(@"<img.*?src=""(.*?)""", RegexOptions.IgnoreCase);
Если это действительный xhtml, вы можете сделать это:
XmlDocument doc = new XmlDocument();
doc.LoadXml(html);
XmlNodeList results = doc.SelectNodes("//img/@src");