用C#怎么提取a标签的超链接?
string reg = @"<a[^>]*href=([""'])?(?<href>[^'""]+)\1[^>]*>";
var item = Regex.Match(str, reg, RegexOptions.IgnoreCase);
Console.WriteLine(item.Groups["href"].Value);
第二种使用htmlagilitypack的xpath进行提取
HtmlNodeCollection atts = _doc.DocumentNode.SelectNodes("//a[@href]");
一般在使用爬虫时都会用自有的框架进行数据提取和分离。其中正则比较简洁和高效。但需要提前调试好。第三方控件使用起来比较容易而且还有其他功能可以辅助使用。
你需要一些用于提取括号的函数:
❶ ListIndex(str, '<', '>') 返回所有尖括号的位置索引。『SortedList<int,int> 』
❷ Cut(str, '\"', '\"') 返回第一个双引号内的内容。『string』
❸ CutAll(str, '<', '>') 返回所有尖括号内的内容。『List<string>』
/// <summary>
/// 获取指定开始字符和结束字符的所有位置。
/// <para>返回一个{int,int}有序列表,Key表示开始字符的位置,Value表示结束位置。</para>
/// <para>"(ad)b(c)b(ea)".ListIndex('(',')') = [0, 3],[5, 7],[9, 12]</para>
/// <para>将忽略处于其他开始和结束字符内部的开始字符。</para>
/// </summary>
public static SortedList<int,int> ListIndex(this string str, char 开始字符, char 结束字符) {
int len = str.Length;
SortedList<int, int> list = new SortedList<int, int>();
if (len < 2) { return list; }
int 开始位置 = 0;
int 结束位置 = 0;
//搜索开始字符
while ((开始位置 = str.IndexOf(开始字符, 开始位置)) != -1) {
//搜索结束字符
while ((结束位置 = str.IndexOf(结束字符, 开始位置 + 1)) != -1) {
list.Add(开始位置, 结束位置);
开始位置 = 结束位置 + 1;
break;
}
}
return list;
}
/// <summary>
/// 截取并返回指定「开始字符」和 「结束字符」之间的字符串。〈<see cref="string"/>〉
/// <para>可以指定是否包括「开始字符」和「结束字符」。默认为不包括。</para>
/// <para>❶ "abcde".Cut('b', 'd', false, false) 返回值 ➤ "c" </para>
/// <para>❷ "abcde".Cut('b', 'd', true, false) 返回值 ➤ "bc" </para>
/// <para>❸ "abcde".Cut('b', 'd', false, true) 返回值 ➤ "cd" </para>
/// <para>❹ "abcde".Cut('b', 'd', true, true) 返回值 ➤ "bcd" </para>
/// <para>如果「开始位置」大于「结束位置」或「开始位置」小于 0 或「结束位置」小于 0 ,则返回空字符串「<see cref="string.Empty"/>」。</para>
/// <para>如果没有「结束字符」,则返回空字符串。</para>
/// </summary>
/// <param name="str">该字符串本身</param>
/// <param name="开始字符">开始的Index,从0开始</param>
/// <param name="结束字符">结束字符char</param>
/// <param name="包括开始字符">默认false。表示返回字符串中不包括开始字符</param>
/// <param name="包括结束字符">默认false。表示返回字符串中不包括开始字符</param>
/// <returns>截取并返回指定 开始位置 和 结束字符 之间的字符串。</returns>
public static string Cut(this string str, char 开始字符, char 结束字符, bool 包括开始字符 = false, bool 包括结束字符 = false) {
int len = str.Length;
int a = 包括开始字符 ? 1 : 0;
int b = 包括结束字符 ? 1 : 0;
int 开始 = str.IndexOf(开始字符, 0);
int t = 开始 + 1;
int 结束 = str.IndexOf(结束字符, t);
if (开始 < 0 || 开始 > 结束 || 结束 < 0) { return ""; }
if (结束 > len) { return str.Substring(t); }
int 长度 = 结束 - t;
return str.Substring(t - a, 长度 + a + b);
}
/// <summary>
/// 指定开始字符和结束字符并返回List截取的字符串。不包括开始字符和结束字符。
/// <para>"adbcbea".Cut('a','b') = {"d"}</para>
/// <para>如果开始位置大于结束位置或小于0,则返回空List(Of String)。</para>
/// <para>如果没有结束字符,则不会识别,返回空List(Of String)。</para>
/// </summary>
public static List<string> CutAll(this string str, char 开始字符, char 结束字符) {
int len = str.Length;
List<string> list = new List<string>();
if (len < 2) { return list; }
bool 已展开 = false;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
char c = str[i];
if (已展开 == false) {
if (c == 开始字符) { 已展开 = true; sb.Clear(); }
} else {
if (c == 结束字符) { 已展开 = false; list.Add(sb.ToString()); } else { sb.Append(c); }
}
}
return list;
}