Búsqueda de sitios web

Diversión del viernes: ¡Es PowerShell, cariño!


El desafío que me propuse fue obtener datos de una tabla y convertirlos en objetos de PowerShell. Cuando ejecuta Invoke-Webrequest desde la consola de PowerShell (no use ISE), obtendrá una propiedad de ParsedHTML. Con esta propiedad puede utilizar Microsoft DOM (modelo de objetos de documento) para analizar datos. Admito que todavía soy un neófito en lo que respecta a trabajar con DOM, pero estoy logrando ese objetivo. De todos modos... al mirar el código fuente de la página, lo cual puedes hacer en cualquier navegador, descubrí que la tabla que quería era la primera de la página. Entonces, comencemos a obtener algunos resultados de PowerShell.

$uri = "http://www.ssa.gov/OACT/babynames/index.html"

#get the data
$data = Invoke-WebRequest $uri

#get the first table
$table = $data.ParsedHtml.getElementsByTagName("table") | Select -first 1

Utilicé el método GetElementsByTagName del DOM para recuperar todas las tablas y luego seleccioné la primera. El objeto de tabla tiene algunas propiedades de texto que podría haber intentado analizar, pero decidí adoptar un enfoque diferente. La tabla contiene filas que puedo obtener.

#get the rows
$rows = $table.rows

El primer elemento de la colección de filas será el encabezado de la tabla. Estos datos se convertirán en las propiedades de mi objeto.

#get table headers
$headers = $rows.item(0).children | select -ExpandProperty InnerText

Ahora, $headers es una matriz de cadenas de cada columna de la tabla. Ahora viene la parte complicada y probablemente haya varias formas de abordar esto. Necesito revisar las filas restantes de la tabla y hacer coincidir cada columna con el encabezado y, finalmente, crear un objeto personalizado. Decidí usar una enumeración For para revisar cada fila y luego, dentro de cada fila, enumerar nuevamente usando los encabezados y agregar cada entrada en una tabla hash, que eventualmente puedo convertir en un objeto personalizado.

#count number of rows
$NumOfRows = $rows | Measure-Object

#enumerate the remaining rows (skipping the header row) and create a custom object
for ($i=1;$i -lt $NumofRows.Count;$i++) {
 #define an empty hashtable
 $objHash=[ordered]@{}
 #get the child rows
 $rowdata = $rows.item($i).children | select -ExpandProperty InnerText 
 for ($j=0;$j -lt $headers.count;$j++) {
    #add each row of data to the hash table using the corresponding
    #table header value
    $objHash.Add($headers[$j],$rowdata[$j])
  } #for

  #turn the hashtable into a custom object
  [pscustomobject]$objHash
} #for

Aquí está el resultado.

Debido a que mi script escribe un objeto en la canalización, también puedo hacer cosas como ordenar y seleccionar.

No puedo garantizar que este código maneje cada tabla con la que se encuentre, pero puede ayudarlo a comenzar y siempre puede pedir ayuda en los foros de PowerShell.org. Si está buscando más ejemplos con Invoke-WebRequest, también puede consultar Obtener lista de cervezas y Explorar cursos de Trainsignal.

¡Disfrutar!

Artículos relacionados