Lectura de textos específicos de un sitio web.

c# html html-agility-pack xpath

Pregunta

Estoy intentando crear una base de datos, pero necesito obtener información de un sitio web. Principalmente el Título, Fecha, Duración y Género del sitio web de IMDB. He intentado como 50 cosas diferentes y simplemente no funciona. Aquí está mi código.

    public string GetName(string URL)
{       
    HtmlWeb web = new HtmlWeb();
    HtmlDocument doc = web.Load(URL);

    var Attr = doc.DocumentNode.SelectNodes("//*[@id=\"overview - top\"]/h1/span[1]@itemprop")[0];

    return Name;
}

Cuando ejecuto esto solo me da una XPathException. Sólo quiero que devuelva el título de una película. Ahora solo uso esta película como ejemplo y prueba, pero quiero que funcione con todas las películas http://www.imdb.com/title/tt0405422 Estoy usando HtmlAgilityPack.

Respuesta aceptada

El último bit de tu XPath no es válido. También para obtener solo un elemento de HtmlDocument() puede usar SelectSingleNode() lugar de SelectNodes() :

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://www.imdb.com/title/tt0405422/");

var xpath = "//*[@id='overview-top']/h1/span[@class='itemprop']";
var span = doc.DocumentNode.SelectSingleNode(xpath);
var title = span.InnerText;

Console.WriteLine(title);

salida:

The 40-Year-Old Virgin

enlace demo: *

https://dotnetfiddle.net/P7U5A7

*) la demostración muestra que se imprime el título correcto, junto con un error específico de .NET Fiddle (puede ignorar el error de forma segura).


Respuesta popular

Estoy haciendo algo familiar y este es mi código que obtiene información del sitio web imdb.com .:

string html = getUrlData(imdbUrl + "combined");
            Id = match(@"<link rel=""canonical"" href=""http://www.imdb.com/title/(tt\d{7})/combined"" />", html);
            if (!string.IsNullOrEmpty(Id))
            {
                status = true;
                Title = match(@"<title>(IMDb \- )*(.*?) \(.*?</title>", html, 2);
                OriginalTitle = match(@"title-extra"">(.*?)<", html);
                Year = match(@"<title>.*?\(.*?(\d{4}).*?\).*?</title>", html);
                Rating = match(@"<b>(\d.\d)/10</b>", html);
                Genres = matchAll(@"<a.*?>(.*?)</a>", match(@"Genre.?:(.*?)(</div>|See more)", html));
                Directors = matchAll(@"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(@"Directed by</a></h5>(.*?)</table>", html));
                Cast = matchAll(@"<td class=""nm""><a.*?href=""/name/.*?/"".*?>(.*?)</a>", match(@"<h3>Cast</h3>(.*?)</table>", html));
                Plot = match(@"Plot:</h5>.*?<div class=""info-content"">(.*?)(<a|</div)", html);
                Runtime = match(@"Runtime:</h5><div class=""info-content"">(\d{1,4}) min[\s]*.*?</div>", html);
                Languages = matchAll(@"<a.*?>(.*?)</a>", match(@"Language.?:(.*?)(</div>|>.?and )", html));
                Countries = matchAll(@"<a.*?>(.*?)</a>", match(@"Country:(.*?)(</div>|>.?and )", html));
                Poster = match(@"<div class=""photo"">.*?<a name=""poster"".*?><img.*?src=""(.*?)"".*?</div>", html);
                if (!string.IsNullOrEmpty(Poster) && Poster.IndexOf("media-imdb.com") > 0)
                {
                    Poster = Regex.Replace(Poster, @"_V1.*?.jpg", "_V1._SY200.jpg");
                    PosterLarge = Regex.Replace(Poster, @"_V1.*?.jpg", "_V1._SY500.jpg");
                    PosterFull = Regex.Replace(Poster, @"_V1.*?.jpg", "_V1._SY0.jpg");
                }
                else
                {
                    Poster = string.Empty;
                    PosterLarge = string.Empty;
                    PosterFull = string.Empty;
                }
                ImdbURL = "http://www.imdb.com/title/" + Id + "/";
                if (GetExtraInfo)
                {
                    string plotHtml = getUrlData(imdbUrl + "plotsummary");
                }

//Match single instance
    private string match(string regex, string html, int i = 1)
    {
        return new Regex(regex, RegexOptions.Multiline).Match(html).Groups[i].Value.Trim();
    }

    //Match all instances and return as ArrayList
    private ArrayList matchAll(string regex, string html, int i = 1)
    {
        ArrayList list = new ArrayList();
        foreach (Match m in new Regex(regex, RegexOptions.Multiline).Matches(html))
            list.Add(m.Groups[i].Value.Trim());
        return list;
    }

Tal vez encuentres algo útil



Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué