在 C# 中使用 htmlagilitypack 解析不同的 HTML
本文关键字:HTML htmlagilitypack | 更新日期: 2023-09-27 18:35:38
我需要一些关于如何使用 htmlagilitypack 和 C# 推广 HTML 解析器的建议。我解析的网页包含员工信息。他们都有a)姓名,ID,地址,电话以下是可能出现也可能不会出现的字段 a) 电子邮件 b) 传真 c) 工作时间 d) Skypeid
Employee 1
<table>
<tr><td nowrap>Name</td><td class="title"><b>Amy</b></td></tr><tr>
<tr><td nowrap>ID</td><td class="title"><b>12345</b></td></tr><tr>
<tr><td nowrap>Address</td><td class="title"><b>36 Main St, Baton Rouge, LA</b></td></tr><tr>
<tr><td nowrap>Telephone</td><td class="title"><b>123-456-7890</b></td></tr><tr>
<tr><td nowrap>Email</td><td class="title"><b>Amy@yahoo.com</b></td></tr><tr>
<tr><td>skypeid</td><td class="title"><b>oilcompany</b></td></tr><tr>
</table>
Employee 2
<table>
<tr><td nowrap>Name</td><td class="title"><b>Cathy</b></td></tr><tr>
<tr><td nowrap>ID</td><td class="title"><b>99345</b></td></tr><tr>
<tr><td nowrap>Address</td><td class="title"><b>36 Main St, Baton Rouge, LA</b></td></tr><tr>
<tr><td nowrap>Telephone</td><td class="title"><b>123-456-7899</b></td></tr><tr>
<tr><td nowrap>Working Hours</td><td class="title"><b>8 PM - 6 AM</b></td></tr><tr>
<tr><td nowrap>fax</td><td class="title"><b>123-456-1111</b></td></tr><tr>
</table>
法典:
HtmlNodeCollection tdNoWraps = hdoc.DocumentNode.SelectNodes("//td[@nowrap]");
HtmlNodeCollection tdNoWrapsclass = hdoc.DocumentNode.SelectNodes("//td[@class]");
if(tdNoWraps != null)
{
if (tdNoWraps[0].InnerText.Trim().Contains("Name"))
dr["Name"] = tdNoWrapsclass[0].InnerText.Trim();
....
}
如您所见,员工 1 与员工不同。如何编写通用解析器?而且"Skypeid"也没有标签,它只是.
谢谢人力资源
从您的示例中,您似乎应该通过"td"(标签)和"td[@class]"(值)来分析记录,因为 Skypeid 不包含 "nowarp" 属性。
检查此示例:
员工对象
public class Employee
{
public string ID { set; get; }
public string Name { set; get; }
public string Address { set; get; }
public string Telephone { set; get; }
public string Email { set; get; }
public string WorkingHours { set; get; }
public string Fax { set; get; }
public string SkypeID { set; get; }
}
我只是建议遍历表,然后在每个循环中,您需要遍历所有"td"元素(在表中),如果"td"没有定义"类",则可以将其视为标签,如果它确实有"类",则它是值(此时您保存数据并继续下一个属性)。
class Program
{
static void Main(string[] args)
{
#region "HTML"
string t = @"<table>
<tr><td nowrap>Name</td><td class=""title""><b>Amy</b></td></tr><tr>
<tr><td nowrap>ID</td><td class=""title""><b>12345</b></td></tr><tr>
<tr><td nowrap>Address</td><td class=""title""><b>36 Main St, Baton Rouge, LA</b></td></tr><tr>
<tr><td nowrap>Telephone</td><td class=""title""><b>123-456-7890</b></td></tr><tr>
<tr><td nowrap>Email</td><td class=""title""><b>Amy@yahoo.com</b></td></tr><tr>
<tr><td>skypeid</td><td class=""title""><b>oilcompany</b></td></tr><tr>
</table>
<table>
<tr><td nowrap>Name</td><td class=""title""><b>Cathy</b></td></tr><tr>
<tr><td nowrap>ID</td><td class=""title""><b>99345</b></td></tr><tr>
<tr><td nowrap>Address</td><td class=""title""><b>36 Main St, Baton Rouge, LA</b></td></tr><tr>
<tr><td nowrap>Telephone</td><td class=""title""><b>123-456-7899</b></td></tr><tr>
<tr><td nowrap>Working Hours</td><td class=""title""><b>8 PM - 6 AM</b></td></tr><tr>
<tr><td nowrap>fax</td><td class=""title""><b>123-456-1111</b></td></tr><tr>
</table> ";
#endregion
var doc = new HtmlDocument();
doc.LoadHtml(t);
var records = doc.DocumentNode.SelectNodes("//table");
List<Employee> employees = new List<Employee>();
foreach (var item in records)
{
var elem = item.Descendants().Where(m => m.Name == "td");
var employee = new Employee();
string elementName = "";
foreach (var row in elem)
{
if (elementName == "")
{
elementName = row.InnerText;
}
if (row.Attributes.Contains("class"))
{
switch (elementName.Trim().ToLower())
{
case "name": employee.Name = row.InnerText.Trim();
break;
case "id": employee.ID = row.InnerText.Trim();
break;
case "address": employee.Address = row.InnerText.Trim();
break;
case "telephone": employee.Telephone = row.InnerText.Trim();
break;
case "email": employee.Email = row.InnerText.Trim();
break;
case "skypeid": employee.SkypeID = row.InnerText.Trim();
break;
case "working hours": employee.WorkingHours = row.InnerText.Trim();
break;
case "fax": employee.Fax = row.InnerText.Trim();
break;
}
elementName = "";
}
}
employees.Add(employee);
}
foreach (var e in employees)
{
Console.WriteLine(e.Name);
}
Console.WriteLine("Press any key...");
Console.ReadLine();
}
}
所以每个员工都在一张桌子上?表中的每一行是雇员的一个属性,第一列是属性名称,第二是实际值。我会把它放到一些员工对象中,比如:
class Employee{
string Name {get; set;}
string ID {get; set;}
string Address {get; set;}
string Telephone {get; set;}
string Email {get; set;}
string Fax {get; set;}
string WorkingHours {get; set;}
string SkypeId {get; set;}
}
您也可以使用 try parse 使其强类型化,但现在只需使用如下所示的内容。
一些边缘情况可能没有被覆盖,代码可能会中断,但我认为你明白了。
HtmlNodeCollection tdNoWraps = hdoc.DocumentNode.SelectNodes("//td[@nowrap]");
HtmlNodeCollection tdNoWrapsclass = hdoc.DocumentNode.SelectNodes("//td[@class]");
var enumeratorNoWrapsClass = tdNoWrapsclass.GetEnumerator();
Employee employee = new Employee();
if(tdNoWraps != null)
{
foreach (var element in tdNoWraps){
if (element.InnerText.Trim().Contains("Name")){
employee.Name = enumeratorNoWrapsClass.Current.InnerText.Trim();
}
....
}
}