#ref(): File not found: "c-sharp-sc.jpg" at page "(wpf)Xpathでスクレイピング"
Xpathでスクレイピングの記事はForm用だから、WPFと組み合わせてみたわ。
とりこみデータサンプルには、投稿小説サイト『小説家になろう』のページを使ってみたわ。実はここのユーザーで投稿者だっていうのもあるんだけど、実は ここの小説本文は、divの特定クラスでXpathを書くと簡単に本文が得られる のよね。
入力は、取り込んだHTMLソースね。詳しくはこっちを見てくれるかしら?ここの末尾にも全ソースを書いておくけど。
なろうサイトの小説本文は、class="novel_view" つきの divで囲まれているの。だからXpathの書き方は「 //div[@class='novel_view'] 」でいいってわけ。ね、テキスト的に簡単でしょう?
private void getXpathProc(string x) { HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument(); html.LoadHtml(x); var articles = html.DocumentNode.SelectNodes(@"//div[@class='novel_view']") .Select(a => new { Html = a.InnerHtml }); tb3.Text = ""; foreach (var a in articles) { string kg = "\r\n"; string x1 = a.Html + kg; tb3.Text += x1; } }
以下には、参考にプログラム全文を入れておくわね。
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" Height="800" Width="800" WindowStyle="ThreeDBorderWindow"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="25" /> <RowDefinition Height="250" /> <RowDefinition Height="200" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="25" /> </Grid.ColumnDefinitions> <TextBox Name="tb1" Grid.Column="0" /> <Button Name="b1" Content="GO" Grid.Column="1" Click="b1_Click" /> </Grid> <WebBrowser Name="web1" Grid.Row="1" LoadCompleted="web1_LoadCompleted" /> <TextBox Name="tb2" Grid.Row="2" VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" /> <TextBox Name="tb3" Grid.Row="3" VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" /> </Grid> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApplication1 { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); webinit(); } private void webinit() { // IWebBrowser2 の取得 プロパティから var axIWebBrowser2 = typeof(WebBrowser).GetProperty("AxIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic); var comObj = axIWebBrowser2.GetValue(web1, null);
// 値の設定 comObj.GetType() .InvokeMember ( "Silent", BindingFlags.SetProperty, null, comObj, new object[] { true } ); } private void web1_LoadCompleted(object sender, NavigationEventArgs e) { this.Title = ((dynamic)web1.Document).Title; tb2.Text = ((dynamic)web1.Document).documentElement.InnerHtml; getXpathProc(tb2.Text); } private void getXpathProc(string x) { HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument(); //html.LoadHtml(((dynamic)web1.Document).Body.InnerHtml); html.LoadHtml(x); var articles = html.DocumentNode.SelectNodes(@"//div[@class='novel_view']") .Select(a => new { Html = a.InnerHtml }); tb3.Text = ""; foreach (var a in articles) { string kg = "\r\n"; string x1 = a.Html + kg; tb3.Text += x1; } } /// <summary> /// Web Access /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void b1_Click(object sender, RoutedEventArgs e) { if (Regex.IsMatch(tb1.Text, @"^http", RegexOptions.IgnoreCase) == true) { web1.Navigate(tb1.Text); } } } }
※ああ、リンク先の権利上の問題は現状ありません。だって自分の書いた三文小説ですもの(汗)