Raspado de pantalla: ¿expresiones regulares o expresiones XQuery?

Estaba respondiendo algunas preguntas del cuestionario para una entrevista, y la pregunta era sobre cómo haría el raspado de pantalla. Es decir, seleccionar contenido de una página web, suponiendo que no tiene una forma mejor estructurada de consultar la información directamente (por ejemplo, un servicio web).

Mi solución fue usar un XQuery expresión. La expresión era bastante larga porque el contenido que necesitaba era bastante profundo en la jerarquía HTML. Tuve que buscar a través de los antepasados de una manera justa antes de encontrar un elemento con unaid atributo. Por ejemplo, el raspado de una página de Amazon.com para Dimensiones del producto se ve así:

//a[@id="productDetails"]
/following-sibling::table
//h2[contains(child::text(), "Product Details")]
/following-sibling::div
//li
/b[contains(child::text(), "Product Dimensions:")]
/following-sibling::text()

Esa es una expresión bastante desagradable, pero es por eso que Amazon ofrece una API de servicio web. De todos modos, es solo un ejemplo. La pregunta no era sobre Amazon, sino sobre el raspado de pantalla.

Al entrevistador no le gustó mi solución. Pensó que era frágil, porque un cambio en el diseño de la página de Amazon podría requerir reescribir la expresión XQuery. La depuración de una expresión XQuery que no coincide con nada en la página a la que se aplica es difícil.

No estuve en desacuerdo con sus declaraciones, pero no pensé que su solución fuera una mejora: pensó que era mejor usar unexpresión regula, y busque contenido y marcas cerca del peso de envío. Por ejemplo, usando Perl:

$html =~ m{<li>\s*<b>\s*Product Dimensions:\s*</b>\s*(.*?)</li>}s;

Mi contraargumento fue que esto también es susceptible a que Amazon cambie su código HTML. Podrían deletrear etiquetas HTML en mayúsculas <LI>), o agregue atributos CSS o cambie<b> a<span> o cambie la etiqueta "Dimensiones del producto:" a "Dimensiones:" o muchos otros tipos de cambios. Mi punto era que las expresiones regulares no resuelven las debilidades que llamó en mi solución XQuery.

Pero además, las expresiones regulares pueden encontrar falsos positivos, a menos que agregue suficiente contexto a la expresión. También puede hacer coincidir involuntariamente el contenido que se encuentra dentro de un comentario, una cadena de atributos o una sección CDATA.

Mi pregunta es, ¿qué tecnología utilizas para raspar la pantalla? ¿Por qué elegiste esa solución? ¿Hay alguna razón convincente para usar uno? ¿O nunca usar el otro? ¿Hay una tercera opción además de las que mostré arriba?

PS: Supongamos, en aras del argumento, que no existe una API de servicio web u otra forma más directa de adquirir el contenido deseado.

Respuestas a la pregunta(8)

Su respuesta a la pregunta