Autor
|
Tema: Leer datos de una tabla html (Leído 9,899 veces)
|
okik
Desconectado
Mensajes: 462
|
Hola buenas, Necesito obtener estos datos y de forma ordenada, en el mismo orden de la tabla. Por ejemplo tengo esta tabla (que he simplificado): <div id="contenedor-portadilla"> <table class="TablaPaises" id="calsificacion_completa"> <th colspan="2" class="sinfondo"> </th> <th colspan="1">Totales </th> <td class="Pais">España </td> <td class="Pais">Portugal </td>
Quedaría así: Totales 1 España 2 Portugal Lo he intentado cargando la página en webbrowser y usando webbrowser.document ... y sus propiedades, el tagname, y eso pero solo he conseguido un listado del <td> sin ningún orden y todo mezclado. yo quiero poder conseguir los datos a voluntad para mostrarlo en un ListView Agradezco cualquier ayuda. Sl2
|
|
« Última modificación: 19 Junio 2015, 03:38 am por okik »
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
Ve analizando la tabla. Buscas las etiquetas tr. Dentro de las tr, localizas las td. Al localizar las td, coges el contenido. Y así con todas las columnas. Basta ir comparando hasta encontrar la cadena deseada (teniendo cuidado de no buscar dentro de comillas).
|
|
|
En línea
|
|
|
|
fran800m
Desconectado
Mensajes: 204
|
Si la respuesta es XHMTL lo más fácil puede ser cargarlo como XmlDocument (creo que se llamaba así la clase) y mediante XPath obtener los nodos td
Si el resultado los cargas en un List (o Array), no recuerdo ahora puedes usar el método Sort para ordenar.
Un saludo,
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.866
|
Un método eficiente para parsear un documento HTML es haciendo uso de la librería (gratuita) profesional HtmlAgilityPack, esta se basa en la utilización de expresiones XPATH. En este ejemplo creo una (simple) Class llamada RowData que servirá para mantener una colección rehutilizable con los datos obtenidos de la tabla: Imports HtmlAgilityPack Public Class Form1 Dim htmlCode As XElement = <html> <div id="contenedor-portadilla"> <table class="TablaPaises" id="calsificacion_completa"> <thead> <tr class="Estadistica"> <th colspan="2" class="sinfondo"></th> <th colspan="1">Totales</th> </tr> </thead> <tbody> <tr> <td class="Num">1</td> <td class="Pais">España</td> </tr> <tr> <td class="Num">2</td> <td class="Pais">Portugal</td> </tr> </tbody> </table> </div> </html> Public Class RowData Public Property Index As Integer Public Property Country As String End Class Private Sub Test() Handles MyBase.Load Dim doc As New HtmlDocument doc.LoadHtml(htmlCode.ToString) Dim tColumnName As String = doc.DocumentNode.SelectSingleNode(".//table[@class='TablaPaises']/thead/tr[@class='Estadistica']/th[@colspan='1']").InnerText Dim tRows As IEnumerable(Of RowData) = From node As HtmlNode In doc.DocumentNode.SelectNodes(".//table[@class='TablaPaises']/tbody/tr") Select New RowData With { .Index = CInt(node.SelectSingleNode(".//td[@class='Num']").InnerText), .Country = node.SelectSingleNode(".//td[@class='Pais']").InnerText.Trim(" "c) } For Each row As RowData In tRows Debug. WriteLine(String. Format("Num: {0}, País: {1}", CStr(row. Index), row. Country)) Next row End Sub End Class
De todas formas, cómo te ha comentado @fran800m puedes parsear un objeto de tipo XElement (o XDocument), puedes utilizar una sintaxis parecida a esta: Dim value As String = htmlCode.<Nombre De Elemento 1>.<Nombre De Elemento 2>.<etc...>.<@Nombre de Atributo>.Value
También puedes usar las funciones built-in de dicha Class XElement para buscar descendientes, ancestros, enumerar las expresiones XPATH disponibles, etc. Saludos!
|
|
« Última modificación: 13 Junio 2015, 20:47 pm por Eleкtro »
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
Cuantas respuestas, muchas gracias Estos días he tenido problemas con la compu, concrectamente con la concexión a Internet (estuve haciendo cosas raras...), pero ya está arreglado. A causa de ello no he podido ver vuestras respuestas. Las vi ayer, pero he estado terminando de recuperar el sistema. Ahora probaré el código de Elektro, a ver que tal. Sl2
|
|
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
De nuevo gracias por las respuestas. Me he descargado Html Agility Pack, pero antes de usarlo he buscado la forma de no depender de librerías externas. He encontrado esta forma usando System.Windows.Forms.HtmlDocument y algo tan viejo como la función InStr. Antes de usar Instr es obtener las líneas <td class="Pais">*</td> mediante miembro OuterHtml de HtmlElement, luego mediante Instr determinar si estamos en "Num" o "Pais" y en cuyo caso se obtiene el InnerText, que sería el número o país. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim doc As HtmlDocument = WebBrowser1.Document Dim divs As HtmlElementCollection = doc.GetElementsByTagName("div") Dim Tipo As String Label1.Text = "" For Each div As HtmlElement In divs If div.GetAttribute("id") = "contenedor-portadilla" Then Dim tables As HtmlElementCollection = doc.GetElementsByTagName("table") For Each table As HtmlElement In tables Dim tds As HtmlElementCollection = table.GetElementsByTagName("td") Dim tdText As String = String.Empty For Each td As HtmlElement In tds tdText = td.InnerText Tipo = td.OuterHtml 'Obtiene la columna "num" ' If InStr(Tipo, "num", CompareMethod.Text) > 0 Then ' Label1.Text = Label1.Text & tdText & vbCrLf ' End If 'Obtiene la columna "pais" If InStr(Tipo, "Pais", CompareMethod.Text) > 0 Then Label1.Text = Label1.Text & tdText & vbCrLf End If Next 'Obtiene la cabezera "Totales" Dim ths As HtmlElementCollection = table.GetElementsByTagName("th") Dim thText As String = String.Empty For Each th As HtmlElement In ths thText = th.InnerText Label1.Text = Label1.Text & thText & vbCrLf Next Next End If Next End Sub
Ignoraba que hacer esto se llama "parsear html", este termino me ha venido muy bien a la hora de buscar en la red sobre este tema y he encontrado otras formas que más adelante probaré. Sl2
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.866
|
He encontrado esta forma usando System.Windows.Forms.HtmlDocument y algo tan viejo como la función InStr. El código que has mostrado está bastante vb6-estilizado. En lugar de la función InStr, puedes utilizar la función String.IndexOf() En lugar de la constante vbCrLf, puedes usar la constante ControlChars.CrLf Saludos!
|
|
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
El código que has mostrado está bastante vb6-estilizado.
En lugar de la función InStr, puedes utilizar la función String.IndexOf()
En lugar de la constante vbCrLf, puedes usar la constante ControlChars.CrLf
Saludos!
Gracias elektro, por la información. No sabía lo de ControlChars.Crlf, pero si uso vbCrlf ¿tampoco pasa nada no?. Quiero decir, que no afecta en nada al programa, supongo. Es más, se me ocurre que también se podría usar ChrW(13). En cuanto a lo de String.IndexOf, eso si que lo sabía. Ahora me doy cuenta que también sirve
|
|
« Última modificación: 18 Junio 2015, 19:16 pm por okik »
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.866
|
Es más, se me ocurre que también se podría usar ChrW(13). El mismo "error" de nuevo. puedes utilizar la función Convert.ToChar. pero si uso vbCrlf ¿tampoco pasa nada no?. Quiero decir, que no afecta en nada al programa, supongo. No, en realidad no pasa nada ...o según se mire, los wrappers de vb6 siguen siendo puro código .Net, pero la razón de que existan es por compatibilidad, esto quiere decir que un buen día podrían dejar de existir, pero, yo te lo comento más que nada por que simplemente el hecho de recurrir a las viejas técnicas o nombres de funciones de VB6 no es algo bueno ya que de alguna manera te estancas en esa tecnología de hace ya casi 2 décadas, y entonces no sigues buenas prácticas de programación en .Net, ya que esto es .Net, no VB6, y, aunque de todas formas sea puro código .Net cómo ya he dicho, si vieras el código fuente de esos wrappers (mediante Reflection) es bastante horrible en comparación con el resto de sus equivalentes funciones built-in que no forman parte del namespace Microsoft.VisualBasic, por ende, te recomiendo no utilizar practicamente ningún miembro que forme parte del namespace Microsoft.VisualBasic, es decir, ningún nombre de función que conozcas de Vb6 plus las constantes y todo eso, ya que todo tiene su equivalente en otras clases más "seguras" y optimizadas de .Net. PD: En mi opinión, es una mala costumbre que les pasa a muchas personas, bien por que hacen la transición de vb6 a .net y preservan sus costumbres, o también a iniciados en VB.Net que hacen copy/pastes de Google, ya que en la mayoría de respuestas que encuentres en Google solo verás morralla vb6-estilizada de programadores que siguen este tipo de prácticas con VB.Net. Saludos!
|
|
« Última modificación: 18 Junio 2015, 22:07 pm por Eleкtro »
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
Bien Elektro, seguiré tu consejo. Al final he encontrado una manera más elegante de obtener el listado de la tabla. Curiosamente al intentar ayudar a otro usuario que trata de loguear y accionar un botón de una web. Antes intentaba encontrar conseguir el atributo "class" y no funcionaba, pues resulta que se llama usando el término "classname". Dim doc As HtmlDocument = WebBrowser1.Document Dim divs As HtmlElementCollection = doc.GetElementsByTagName("td") For Each div As HtmlElement In divs If div.GetAttribute("classname") = "Pais" Then ListBox1.Items.Add(div.InnerText) End If Next
y otra forma, esta. Pero solo obtiene el primero, porque no repasa cada elemento Dim ele = webbrowser1.Document.GetElementsByTagName("td").Cast(Of HtmlElement).First(Function(el) el.GetAttribute("classname") = "Pais") ListBox1.Items.Add(ele.InnerText)
y aunque en el ejemplo uso el control Webbrowser1 se puede crear una variable objeto como un webbrowser
|
|
« Última modificación: 19 Junio 2015, 03:37 am por okik »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Organizar Tabla HTML
PHP
|
^Tifa^
|
4
|
3,602
|
26 Abril 2009, 22:44 pm
por дٳŦ٭
|
|
|
extraer html (tabla) con php
PHP
|
schumacher
|
2
|
4,329
|
25 Mayo 2012, 07:37 am
por engel lex
|
|
|
python y tabla HTML
Scripting
|
Alfai
|
3
|
4,689
|
17 Agosto 2009, 00:04 am
por Alfai
|
|
|
Duda sobre insersion a tabla html desde tabla sql
Bases de Datos
|
mokoMonster
|
2
|
4,119
|
20 Febrero 2010, 01:20 am
por Shell Root
|
|
|
Html leer datos
Desarrollo Web
|
DameBanda
|
5
|
5,075
|
16 Noviembre 2011, 16:58 pm
por RyogiShiki
|
|