インターネット上のhtmlファイルを取得し、その内容から必要な部分を正規表現で取り出す方法、そして、相対uriと絶対uriを相互に変換する方法を見てきました。
それを踏まえて、htmlファイル内のaタグ内のuriを絶対uriに変換し、変換が正常に行われているか確認できるように、UIにその変換結果を表示するプログラムを作成することにしました。
まずは、UIウィンドウを作成します。
MainWindow.xamlを以下のコードを参考に変更して下さい。
<Window x:Class="WebRegex03.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<DockPanel DockPanel.Dock="Top">
<Button DockPanel.Dock="Right"
Width="100" Click="Button_Click">実行</Button>
<TextBox Name="urlAcsses"
AcceptsReturn="True"
VerticalScrollBarVisibility="Auto">TextBox</TextBox>
</DockPanel>
<TextBox Name="htmlText">TextBox</TextBox>
</DockPanel>
<GridSplitter Grid.Row="1" Height="2" HorizontalAlignment="Stretch" />
<DockPanel Grid.Row="2">
<DataGrid Name="dataGrid" />
</DockPanel>
</Grid>
</Window>
新しいクラスファイルData.csを作成し、データを格納するクラスのコードを入力します。
namespace WebRegex03
{
public class UriData
{
public string BaseUri{ get; set; } // 基準Uri
public string RelUri { get; set; } // 相対Uri
public string AbsUri { get; set; } // 絶対Uri
}
}
MainWindow.xaml.csを以下のコードを参考に変更して下さい。
using System.Collections.Generic;
using System.Windows;
namespace WebRegex03
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
urlAcsses.Text = uriAdress;
}
private string uriAdress = "https://webdesign.vdlz.xyz/index.html";
private string regexFormula = "<a href=\"(.*?)\".*?>";
public List<UriData> myUri = new List<UriData>();
private void Button_Click(object sender, RoutedEventArgs e)
{
// htmltテキストをインターネットから取得する
GetHtmlTexte gethtml = new GetHtmlTexte(uriAdress);
// 取得したhtmlテキストをテキストボックスに入力する
htmlText.Text = gethtml.result;
// htmlテキストから、aタグで指定されたuriを取得し、相対uriを絶対uriに変換する
DoRegexParts RResult = new DoRegexParts(regexFormula, htmlText.Text, uriAdress);
// uriをデータグリッドに表示する
this.dataGrid.ItemsSource = RResult.UriDataList;
}
}
}
新しいクラスファイルModel.csを作成し、インターネットから、htmlファイルの内容を取得するコード、aタグで示された、uriを取得するコード、相対uriを絶対uriに変換するコードを入力します。
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
namespace WebRegex03
{
class GetHtmlTexte
{
// 取得したhtmlテキスト
public string result;
// コンストラクタ urlを与えると、resultにhtmlテキストを入力する
public GetHtmlTexte(string url)
{
WebClient wc = new WebClient();
try
{
using (Stream stream = wc.OpenRead(url))
using (StreamReader sr = new StreamReader(stream))
{
// Add a user agent header in case the
// requested URI contains a query.
// 要求されたURIに、問合せが含まれる場合に備えて、
// ユーザー・エージェント・ヘッダを追加します。
wc.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
string str = sr.ReadToEnd();
result = str;
}
}
catch
{
// Let the user know what went wrong.
// ユーザーに、何が問題になったのかを知らせます。
// The file could not be read:
result = "指定されたサイトを読み取れませんでした:";
}
}
}
class DoRegexParts
{
// 部分一致 1つ目のグループを取得
// 正規表現パターンを格納
private string regexPattern;
// 取得した一致パターンを格納
private object uriAdress;
public List<UriData> UriDataList = new List<UriData>();
public DoRegexParts(string pattern, string targetStr, string _baseUri)
{
Regex r = new Regex(pattern);
//基準uriを取得する
Uri _BaseUri = new Uri(_baseUri);
Match m = r.Match(targetStr);
while (m.Success)
{
string _relUri = m.Groups[1].ToString();
// 絶対uriを取得する
Uri myUri = new Uri(_BaseUri, _relUri);
UriData uriData = new UriData
{
BaseUri = _baseUri,
RelUri = _relUri,
AbsUri = myUri.AbsoluteUri
};
UriDataList.Add(uriData);
m = m.NextMatch();
}
}
}
}
実行結果
末尾の/は、元の表記が反映されるようです。重複を削除する際に注意する必要があります。