웹 사이트에서 C #으로 HTML 코드 가져 오기


87

웹 사이트에서 HTML 코드를 가져와 저장하고 LINQ 식으로 텍스트를 찾는 방법은 무엇입니까?

웹 페이지의 소스를 가져 오기 위해 다음 코드를 사용하고 있습니다.

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;
 }

웹 페이지 소스의 div에서 텍스트를 어떻게 찾습니까?


스마트 검색이 얼마나 필요한지에 따라 다릅니다. 간단한 Contains전화가 "충분히 좋다"고 할 수 있습니다.
ashes999 2013 년

5
HTML이 있으면 HTMLAgility 팩, Fizzler 또는 CSQuery를 사용하여 div / 텍스트를 가져 오십시오. 다른 것은 오류가 발생하기 쉽습니다.
jammykam 2013 년


@GeorgeDuckett 그것은이 질문의 중복처럼 보이지 않습니다. 링크하는 질문은 소스 검색에 관한 것입니다.이 질문은 DOM 쿼리에 관한 것입니다.
Mark Rotteveel 2013 년

@Mark : 죄송합니다. 맞습니다. 하단의 텍스트를 놓쳤습니다.
George Duckett 2013 년

답변:


112

웹 사이트에서 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();
}

웹 사이트에서 반환 된 HTML 코드 가 제공됩니다 . 그러나 LINQ 를 통해 텍스트를 찾는 것은 그렇게 쉽지 않습니다. 정규 표현식을 사용하는 것이 더 낫지 만 HTML 코드에서는 잘 작동하지 않습니다.


4
html 또는 XML에 정규식을 사용하는 아이디어는 매우 나쁜 코딩 관행입니다 ... 당신의 방식대로-우리는 어디에서나 goto 키워드를 사용해야합니다 ...
Lightning3

실제로 정규식을 사용하여 HTML 코드 내에서 정확한 것을 검색하는 것은 매우 적절한 솔루션이 될 수 있습니다. 반면에 정규식을 기반으로 HTML 파서 / 인터프리터를 구축하려는 시도는 순수한 광기 일 것입니다. 그것은 모두 컨텍스트와 수행해야하는 실제 작업에 따라 다르지만 "정규식은 HTML과 잘 어울리지 않는다"는 말은 전 세계적이고 설명 할 수없는 진실이 아닙니다. stackoverflow.com/a/1733489/6838730
Mathieu VIALES

177

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

9
의 경우 using1 : 분명히 사용에 모두를위한 표시 요구 사항
user3916429

37

사용하기 가장 좋은 것은 HTMLAgilityPack 입니다. 검색된 페이지에서 요소를 선택하기위한 필요에 따라 Fizzler 또는 CSQuery 를 사용할 수도 있습니다 . LINQ 또는 Regukar Expressions를 사용하면 오류가 발생하기 쉽습니다.

페이지를 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;
}

나는 그것이 그것보다 더 간단해질 수 있다고 생각하지 않습니다.


웹 페이지에서 특정 버튼을 호출하려면 어떻게해야합니까? @jammykam
Jamshaid 캄란

1
화면 스크레이퍼 afaik으로는이를 수행 할 수 없으며 버튼을 호출하려면 Selenium과 같은 것을 사용해야합니다.
jammykam

FizzlerEx를 어떻게 설치합니까? 나는 링크를 확인하고이 .zip가 있지만 설치 프로그램이 표시되지 않습니다
후안 카를로스 Oropeza

5

저는 AngleSharp를 사용 하고 있으며 매우 만족합니다.

다음은 페이지를 가져 오는 간단한 예입니다.

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

이제 문서 변수에 웹 페이지가 있습니다 . 그런 다음 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.