さて、ライブWebサイトにクエリを実行してテーブルからデータを取得し、このHTMLテーブルをDataTableに配置してから、このデータを使用する必要があります。これまで、Html Agility PackとXPathを使用して、必要なテーブルの各行にアクセスできましたが、DataTableに解析する方法が必要であることはわかっています。 (C#)現在使用しているコードは次のとおりです。
string htmlCode = "";
using (WebClient client = new WebClient())
{
htmlCode = client.DownloadString("http://www.website.com");
}
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(htmlCode);
//My attempt at LINQ to solve the issue (not sure where to go from here)
var myTable = doc.DocumentNode
.Descendants("table")
.Where(t =>t.Attributes["summary"].Value == "Table One")
.FirstOrDefault();
//Finds all the odd rows (which are the ones I actually need but would prefer a
//DataTable containing all the rows!
foreach (HtmlNode cell in doc.DocumentNode.SelectNodes("//tr[@class='odd']/td"))
{
string test = cell.InnerText;
//Have not gone further than this yet!
}
クエリを実行しているWebサイトのHTMLテーブルは次のようになります。
<table summary="Table One">
<tbody>
<tr class="odd">
<td>Some Text</td>
<td>Some Value</td>
</tr>
<tr class="even">
<td>Some Text1</td>
<td>Some Value1</td>
</tr>
<tr class="odd">
<td>Some Text2</td>
<td>Some Value2</td>
</tr>
<tr class="even">
<td>Some Text3</td>
<td>Some Value3</td>
</tr>
<tr class="odd">
<td>Some Text4</td>
<td>Some Value4</td>
</tr>
</tbody>
</table>
LINQ + HAPまたはXPath + HAPを使用して目的の結果を得る方が良い/簡単かどうかはわかりませんが、おそらくわかるように、両方を試しましたが、成功は限られていました。ウェブサイトにクエリを実行したり、何らかの方法でウェブサイトとやり取りしたりするプログラムを作成したのはこれが初めてなので、現時点では非常に確信が持てません。事前に助けてくれてありがとう:)
HTML Agility Packには、すぐに使用できるそのようなメソッドはありませんが、作成するのはそれほど難しくありません。 LinqからXMLへのXMLからDatatableへのXMLを実行する そこにあるサンプル があります。これらは、必要なものに作り直すことができます。
必要に応じて、メソッド全体の作成を手伝うことができますが、今日はできません:)。
参照:
上記のJackEkerのコードとMarkGravellのコード( ここの投稿を参照 )を使用して、なんとか解決策を思いついた。このコードスニペットは、この記事の執筆時点で南アフリカの2012年の祝日を取得するために使用されます。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web;
using System.Net;
using HtmlAgilityPack;
namespace WindowsFormsApplication
{
public partial class Form1 : Form
{
private DataTable dt;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string htmlCode = "";
using (WebClient client = new WebClient())
{
client.Headers.Add(HttpRequestHeader.UserAgent, "AvoidError");
htmlCode = client.DownloadString("http://www.info.gov.za/aboutsa/holidays.htm");
}
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(htmlCode);
dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Value", typeof(string));
int count = 0;
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table"))
{
foreach (HtmlNode row in table.SelectNodes("tr"))
{
if (table.Id == "table2")
{
DataRow dr = dt.NewRow();
foreach (var cell in row.SelectNodes("td"))
{
if ((count % 2 == 0))
{
dr["Name"] = cell.InnerText.Replace(" ", " ");
}
else
{
dr["Value"] = cell.InnerText.Replace(" ", " ");
dt.Rows.Add(dr);
}
count++;
}
}
}
dataGridView1.DataSource = dt;
}
}
}
}
これが私の解決策です。少し厄介かもしれませんが、現時点では完全に機能しています:D
string htmlCode = "";
using (WebClient client = new WebClient())
{
client.Headers.Add(HttpRequestHeader.UserAgent, "AvoidError");
htmlCode = client.DownloadString("http://www.website.com");
}
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(htmlCode);
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Value", typeof(decimal));
int count = 0;
decimal rowValue = 0;
bool isDecimal = false;
foreach (var row in doc.DocumentNode.SelectNodes("//table[@summary='Table Name']/tbody/tr"))
{
DataRow dr = dt.NewRow();
foreach (var cell in row.SelectNodes("td"))
{
if ((count % 2 == 0))
{
dr["Name"] = cell.InnerText.Replace(" ", " ");
}
else
{
isDecimal = decimal.TryParse((cell.InnerText.Replace(".", "")).Replace(",", "."), out rowValue);
if (isDecimal)
{
dr["Value"] = rowValue;
}
dt.Rows.Add(dr);
}
count++;
}
}
Htmltableをdatatableに変換する単純なロジック:
//Define your webtable
public static HtmlTable table
{
get
{
HtmlTable var = new HtmlTable(parent);
var.SearchProperties.Add("id", "searchId");
return var;
}
}
//Convert a webtable to datatable
public static DataTable getTable
{
get
{
DataTable dtTable= new DataTable("TableName");
UITestControlCollection rows = table.Rows;
UITestControlCollection headers = rows[0].GetChildren();
foreach (HtmlHeaderCell header in headers)
{
if (header.InnerText != null)
dtTable.Columns.Add(header.InnerText);
}
for (int i = 1; i < rows.Count; i++)
{
UITestControlCollection cells = rows[i].GetChildren();
string[] data = new string[cells.Count];
int counter = 0;
foreach (HtmlCell cell in cells)
{
if (cell.InnerText != null)
data[counter] = cell.InnerText;
counter++;
}
dtTable.Rows.Add(data);
}
return dtTable;
}
}
あなたが試すことができます
DataTable.Rows[i].Cells[j].InnerText;
DataTableがテーブルのIDである場合、iは行、jはセルです。