C#のWebサイトからHTMLコードを取得する


89

WebサイトからHTMLコードを取得して保存し、LINQ式でテキストを見つける方法は?

次のコードを使用して、Webページのソースを取得しています。

public static String code(string Url)
{
    HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(Url);
    myRequest.Method = "GET";
    WebResponse myResponse = myRequest.GetResponse();
    StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
    string result = sr.ReadToEnd();
    sr.Close();
    myResponse.Close();

    return result;
 }

Webページのソースのdiv内のテキストを見つけるにはどうすればよいですか?


スマート検索のあり方によって異なります。単純なContains呼び出しで「十分」な場合があります。
ashes999 2013年

5
HTMLを取得したら、HTMLAgilityパック、Fizzler、またはCSQueryを使用してdiv / textを取得することを検討してください。それ以外の場合は、エラーが発生しやすくなります。
jammykam 2013年


@GeorgeDuckettこれはこの質問の重複のようには見えません。リンク先の質問はソースの取得に関するものであり、この質問はDOMのクエリに関するものでもあります。
Mark Rotteveel 2013年

@マーク:申し訳ありませんが、その通りです。下部のテキストを見逃しました。
ジョージダケット

回答:


113

WebサイトからHTMLコードを取得する。このようなコードを使用できます。

string urlAddress = "http://google.com";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

if (response.StatusCode == HttpStatusCode.OK)
{
  Stream receiveStream = response.GetResponseStream();
  StreamReader readStream = null;

  if (String.IsNullOrWhiteSpace(response.CharacterSet))
     readStream = new StreamReader(receiveStream);
  else
     readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));

  string data = readStream.ReadToEnd();

  response.Close();
  readStream.Close();
}

これにより、Webサイトから返されたHTMLコードが提供されます。しかし、LINQを介してテキストを見つけるのはそれほど簡単ではありません。おそらく正規表現を使用する方が良いでしょうが、それはHTMLコードではうまく機能しません


4
HTMLやXMLのための正規表現を使用してのアイデアは、あなたの方法で行く...の練習をコーディング非常に悪いです-私たちはどこにでもキーワード後藤使用する必要があります...
Lightning3

1
実際、正規表現を使用してHTMLコード内の正確なものを検索することは、非常に適切な解決策になる可能性があります。一方、正規表現に基づいてHTMLパーサー/インタープリターを構築しようとすると、純粋な狂気になります。それはすべて、実行する必要のあるコンテキストと実際のタスクに依存しますが、「正規表現はHTMLでうまく機能しない」と言うことは、単にグローバルで、解決できない真実ではありません。 stackoverflow.com/a/1733489/6838730
Mathieu VIALES 2018年

183

Webclientクラスを使用して、タスクを単純化することをお勧めします。

using System.Net;

using (WebClient client = new WebClient())
{
    string htmlCode = client.DownloadString("http://somesite.com/default.html");
}

このエラーが発生する理由はありますか?'System.Net.WebClient':usingステートメントで使用されるタイプは暗黙的に 'System.IDisposable'に変換可能である必要があります
Dave Chandler

10
以下の場合using1:明らかに使用するすべての人のために示した要件
user3916429

http 403エラーが発生している場合は、client.Headers.Add( "user-agent"、 "Fiddler");を追加します。Fiddlerを任意のテキストに置き換えます。
HimanshuPatel20年

37

使用するのに最適なのはHTMLAgilityPackです。取得したページから要素を選択する必要性に応じて、FizzlerまたはCSQueryの使用を検討することもできます。LINQまたはRegukar式の使用は、特にHTMLの形式が正しくない、終了タグがない、子要素がネストされているなどの場合に、エラーが発生しやすくなります。

ページをHtmlDocumentオブジェクトにストリーミングしてから、必要な要素を選択する必要があります。

// Call the page and get the generated HTML
var doc = new HtmlAgilityPack.HtmlDocument();
HtmlAgilityPack.HtmlNode.ElementsFlags["br"] = HtmlAgilityPack.HtmlElementFlag.Empty;
doc.OptionWriteEmptyNodes = true;

try
{
    var webRequest = HttpWebRequest.Create(pageUrl);
    Stream stream = webRequest.GetResponse().GetResponseStream();
    doc.Load(stream);
    stream.Close();
}
catch (System.UriFormatException uex)
{
    Log.Fatal("There was an error in the format of the url: " + itemUrl, uex);
    throw;
}
catch (System.Net.WebException wex)
{
    Log.Fatal("There was an error connecting to the url: " + itemUrl, wex);
    throw;
}

//get the div by id and then get the inner text 
string testDivSelector = "//div[@id='test']";
var divString = doc.DocumentNode.SelectSingleNode(testDivSelector).InnerHtml.ToString();

[編集]実際、それをスクラップします。最も簡単な方法は、元のFizzlerプロジェクトの更新されたjQuery / CSS3セレクター実装であるFizzlerExを使用することです

彼らのサイトから直接サンプルをコード化する:

using HtmlAgilityPack;
using Fizzler.Systems.HtmlAgilityPack;

//get the page
var web = new HtmlWeb();
var document = web.Load("http://example.com/page.html");
var page = document.DocumentNode;

//loop through all div tags with item css class
foreach(var item in page.QuerySelectorAll("div.item"))
{
    var title = item.QuerySelector("h3:not(.share)").InnerText;
    var date = DateTime.Parse(item.QuerySelector("span:eq(2)").InnerText);
    var description = item.QuerySelector("span:has(b)").InnerHtml;
}

それ以上に簡単になるとは思いません。


Webページの特定のボタンを呼び出したい場合はどうすればよいですか?@jammykam
Jamshaid K.

1
スクリーンスクレイパーafaikではそれを行うことはできません。ボタンを呼び出すには、Seleniumなどを使用する必要があります。
jammykam 2017

FizzlerExをどのようにインストールしますか?リンクを確認しましたが、.zipがありますが、インストーラーが表示されません
Juan CarlosOropeza19年

6

私はAngleSharpを使用していて、非常に満足しています。

ページをフェッチする簡単な例を次に示します。

var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync("https://www.google.com");

これで、ドキュメント変数にWebページができました。その後、LINQまたは他の方法で簡単にアクセスできます。たとえば、HTMLテーブルから文字列値を取得する場合:

var someStringValue = document.All.Where(m =>
        m.LocalName == "td" &&
        m.HasAttribute("class") &&
        m.GetAttribute("class").Contains("pid-1-bid")
    ).ElementAt(0).TextContent.ToString();

CSSセレクターを使用するには、AngleSharpの例を参照してください。


5

HttpWebRequestクラスを使用してURLをフェッチする例を次に示します。

private void buttonl_Click(object sender, EventArgs e) 
{ 
    String url = TextBox_url.Text;
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url); 
    HttpWebResponse response = (HttpWebResponse) request.GetResponse(); 
    StreamReader sr = new StreamReader(response.GetResponseStream()); 
    richTextBox1.Text = sr.ReadToEnd(); 
    sr.Close(); 
} 

2
画像の代わりにコードを回答に追加する必要があります。
AJ

2

WebClientを使用して、任意のURLのhtmlをダウンロードできます。HTMLを取得たらHtmlAgilityPackなどのサードパーティライブラリを使用して、以下のコードのようにHTML内の値を検索できます-

public static string GetInnerHtmlFromDiv(string url)
    {
        string HTML;
        using (var wc = new WebClient())
        {
            HTML = wc.DownloadString(url);
        }
        var doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(HTML);
        
        HtmlNode element = doc.DocumentNode.SelectSingleNode("//div[@id='<div id here>']");
        if (element != null)
        {
            return element.InnerHtml.ToString();
        }   
        return null;            
    }

1

このソリューションを試してください。それはうまくいきます。

 try{
        String url = textBox1.Text;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        StreamReader sr = new StreamReader(response.GetResponseStream());
        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
        doc.Load(sr);
        var aTags = doc.DocumentNode.SelectNodes("//a");
        int counter = 1;
        if (aTags != null)
        {
            foreach (var aTag in aTags)
            {
                richTextBox1.Text +=  aTag.InnerHtml +  "\n" ;
                counter++;
            }
        }
        sr.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Failed to retrieve related keywords." + ex);
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.