我需要一些关于如何使用htmlagilitypack和C#来概括HTML解析器的建议。我解析的网页包含员工信息。所有这些都有a)姓名,身份证,地址,电话 以下是可能出现或未出现的字段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'也没有标签它只是。
由于 HR
答案 0 :(得分:0)
所以每个员工都在一张桌子里? 表中的每一行都是员工的一个属性,第一列是属性名称,第二列是实际值。 我会把它放到一些Employee对象中,如:
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();
}
....
}
}
答案 1 :(得分:0)
从您的示例中,您似乎应该通过“td”(标签)和“td [@class]&#34;解析记录。 (值)因为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();
}
}