Pregunta

He guardado el html de una página web completa en una cadena, y ahora quiero tomar el " href " valores de los enlaces, preferiblemente con la posibilidad de guardarlos en diferentes cadenas más adelante. ¿Cuál es la mejor manera de hacer esto?

He intentado guardar la cadena como un documento .xml y analizarlo usando un navegador XPathDocument, pero (sorpresa sorpresa) no navega demasiado bien en un documento que no es realmente un xml.

¿Las expresiones regulares son la mejor forma de lograr lo que estoy tratando de lograr?

¿Fue útil?

Solución

Las expresiones regulares son una forma de hacerlo, pero puede ser problemático.

La mayoría de las páginas HTML no se pueden analizar utilizando técnicas html estándar porque, como descubrió, la mayoría no se validan.

Puede pasar el tiempo intentando integrar HTML Tidy o una herramienta similar, pero sería mucho más rápido para crear la expresión regular que necesita.

UPDATE

En el momento de esta actualización, he recibido 15 upvotes y 9 downvotes. Creo que tal vez la gente no está leyendo la pregunta ni los comentarios sobre esta respuesta. Todo lo que el OP quería hacer era tomar los valores href. Eso es todo. Desde esa perspectiva, una expresión regular simple está bien. Si el autor hubiera querido analizar otros elementos, entonces no hay forma de recomendar la expresión regular como dije al principio, es problemático en el mejor de los casos.

Otros consejos

Puedo recomendar el Paquete de agilidad HTML . Lo he usado en algunos casos en los que necesitaba analizar HTML y funciona muy bien. Una vez que cargue su HTML en él, puede usar expresiones XPath para consultar el documento y obtenga sus etiquetas de anclaje (así como casi cualquier otra cosa allí).

HtmlDocument yourDoc = // load your HTML;
int someCount = yourDoc.DocumentNode.SelectNodes("your_xpath").Count;

Para tratar con HTML de todas las formas y tamaños, prefiero usar el paquete HTMLAgility @ http: //www.codeplex .com / htmlagilitypack le permite escribir XPaths contra los nodos que desee y obtener esos retornos en una colección.

Probablemente desee algo como el analizador Majestic: http: //www.majestic12. co.uk/projects/html_parser.php

Hay algunas otras opciones que también pueden ocuparse del html escamoso. Vale la pena echarle un vistazo al paquete de agilidad HTML, como alguien más mencionó.

No creo que las expresiones regulares sean una solución ideal para HTML, ya que HTML no está libre de contexto. Probablemente producirán un resultado adecuado, aunque impreciso; incluso determinar determinísticamente un URI es un problema complicado.

Siempre es mejor, si es posible, no redescubrir la rueda. Existen algunas buenas herramientas que convierten HTML a XML bien formado o actúan como XmlReader:

Aquí hay tres buenas herramientas:

  1. TagSoup , un programa de código abierto, es una herramienta basada en Java y SAX, desarrollada por John Cowan . Esto es un analizador compatible con SAX escrito en Java que, en lugar de analizar XML bien formado o válido, analiza HTML como se encuentra en la naturaleza: pobre, desagradable y brutal, aunque a menudo está lejos de ser breve. TagSoup está diseñado para personas que tienen que procesar estas cosas utilizando una apariencia de diseño de aplicación racional. Al proporcionar una interfaz SAX, permite que las herramientas XML estándar se apliquen incluso al peor HTML. TagSoup también incluye un procesador de línea de comandos que lee archivos HTML y puede generar HTML limpio o XML bien formado que es una aproximación cercana a XHTML.
    Taggle es un puerto comercial C ++ de TagSoup.

  2. SgmlReader es una herramienta desarrollada por Microsoft Chris Lovett .
    SgmlReader es una API XmlReader sobre cualquier documento SGML (incluido el soporte integrado para HTML). También se proporciona una utilidad de línea de comandos que genera el resultado XML bien formado.
    Descargue el archivo zip que incluye el ejecutable independiente y el código fuente completo: SgmlReader.zip

  3. Un logro sobresaliente es el puro analizador XSLT 2.0 de HTML escrito por David Carlisle .

Leer su código sería un gran ejercicio de aprendizaje para todos nosotros.

De la descripción:

" d: htmlparse (cadena)
& nbsp; d: htmlparse (cadena, espacio de nombres, modo html)

& nbsp; & nbsp; La forma de un argumento es equivalente a)
& nbsp; & nbsp; d: htmlparse (cadena, ' http://ww.w3.org/1999/xhtml ', true ()))

& nbsp; & nbsp; Analiza la cadena como HTML y / o XML utilizando algunas heurísticas incorporadas para)
& nbsp; & nbsp; controla la apertura y cierre implícito de elementos.

& nbsp; & nbsp; No tiene pleno conocimiento de HTML DTD pero tiene una lista completa de
& nbsp; & nbsp; elementos vacíos y lista completa de definiciones de entidad. Entidades HTML y
& nbsp; & nbsp; se aceptan referencias de caracteres decimales y hexadecimales. Tenga en cuenta las entidades html
& nbsp; & nbsp; se reconocen incluso si html-mode = false ().

& nbsp; & nbsp; Los nombres de los elementos están en minúsculas (si html-mode es verdadero ()) y se colocan en el
& nbsp; & nbsp; espacio de nombres especificado por el parámetro de espacio de nombres (que puede ser " " para indicar
& nbsp; & nbsp; no-namespace a menos que la entrada tenga declaraciones explícitas de espacio de nombres, en
& nbsp; & nbsp; en cuyo caso estos serán respetados.

& nbsp; & nbsp; Los nombres de los atributos están en minúsculas si html-mode = true ()
"

Lea una descripción más detallada aquí .

Espero que esto haya ayudado.

Saludos,

Dimitre Novatchev.

Estoy de acuerdo con Chris Lively, ya que HTML a menudo no está muy bien formado, probablemente sea mejor con una expresión regular para esto.

href=[\"\'](http:\/\/|\.\/|\/)?\w+(\.\w+)*(\/\w+(\.\w+)?)*(\/|\?\w*=\w*(&\w*=\w*)*)?[\"\']

De aquí en RegExLib debería ayudarlo a comenzar

Es posible que tenga más suerte usando xml si sabe o puede arreglar que el documento esté al menos bien formado. Si tiene bueno html (o más bien, xhtml), el sistema xml en .Net debería poder manejarlo. Desafortunadamente, un buen HTML es extremadamente raro.

Por otro lado, las expresiones regulares son realmente malas al analizar html. Afortunadamente, no necesita manejar una especificación html completa. De lo único que debe preocuparse es de analizar las cadenas href = para obtener la url. Incluso esto puede ser complicado, por lo que no lo intentaré de inmediato. En cambio, comenzaré haciendo algunas preguntas para tratar de establecer algunas reglas básicas. Básicamente, todos se reducen a "¿Cuánto sabes sobre el documento?", Pero aquí va:

  • ¿Sabes si el " href " el texto siempre estará en minúscula?
  • ¿Sabes si siempre usará comillas dobles, comillas simples o nada alrededor de la URL?
  • ¿Siempre es una URL válida o necesita dar cuenta de cosas como '#', declaraciones de JavaScript y similares?
  • ¿Es posible trabajar con un documento donde el contenido describe características html (IE: href = también podría estar en el documento y no pertenecer a una etiqueta de anclaje)?
  • ¿Qué más nos puede decir sobre el documento?

He vinculado un código aquí que le permitirá usar "LINQ to HTML" ...

Buscando el analizador HTML C #

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top