2012-05-03 16 views
5

Estoy investigando la posibilidad de transferir la biblioteca de Python Beautiful Soup a .NET. Principalmente, porque realmente amo el analizador y simplemente no hay buenos analizadores HTML en .NET Framework (Html ​​Agility Pack está desactualizado, con errores, no documentado y no funciona bien a menos que se conozca el esquema exacto).Transmitir una biblioteca muy Pythonesque a .NET

Uno de Mi objetivo principal es conseguir que la funcionalidad básica de selección de DOM sea realmente paralela a la belleza y simplicidad de BeautifulSoup, permitiendo a los desarrolladores crear fácilmente expresiones para encontrar los elementos que están buscando.

BeautifulSoup aprovecha los parámetros vinculados y nombrados para hacer que esto ocurra. Por ejemplo, para encontrar todos a etiquetas con un id de test y una title que contiene la palabra foo, lo que podía hacer:

soup.find_all('a', id='test', title=re.compile('foo')) 

Sin embargo, C# no tiene un concepto de un número arbitrario de llamada elementos. .NET4 Runtime tiene parámetros nombrados, sin embargo, deben coincidir con un prototipo de método existente.

Mi pregunta: ¿Cuál es el patrón de diseño C# que más se asemeja a este constructo pitónico?

Algunas ideas:

me gustaría ir después de esto sobre la base de la forma en que, como desarrollador, quisiera codificar. La implementación de esto está fuera del alcance de esta publicación. Una idea que tengo es usar tipos anónimos. Algo así como:

soup.FindAll("a", new { Id = "Test", Title = new Regex("foo") }); 

Aunque esta sintaxis coincide vagamente la implementación de Python, todavía tiene algunas desventajas.

  1. La aplicación FindAll tendría que utilizar la reflexión para analizar el tipo anónimo, y manejar cualquier metadatos arbitraria de una manera razonable.
  2. El prototipo FindAll necesitaría tomar un Object, lo que deja bastante claro cómo usar el método a menos que esté familiarizado con el comportamiento documentado. No creo que haya una manera de declarar un método que debe tomar un tipo anónimo.

Otra idea que tuve es quizás una forma más de .NET de manejar esto, pero se aleja más de las raíces de Python de la biblioteca. Eso sería usar un patrón fluido. Algo como:

soup.FindAll("a") 
    .Attr("id", "Test") 
    .Attr("title", new Regex("foo")); 

Esto requeriría construir un árbol de expresiones y localizar los nodos apropiados en el DOM.

La tercera y última idea que tengo es usar LINQ. Algo así como:

var nodes = (from n in soup 
      where n.Tag == "a" && 
      n["id"] == "Test" && 
      Regex.Match(n["title"], "foo").Success 
      select n); 

Apreciaría cualquier penetración de cualquier persona con experiencia portar código Python a C#, o simplemente recomendaciones generales sobre la mejor manera de manejar esta situación.

+7

Tanto como me encanta Python: siempre apunte a la audiencia que lo usará. Si está escribiendo para .NET, hágalo en el estilo que usan. Mire las bibliotecas .NET existentes y vea cuáles son las prácticas (o espere que alguien le cuente aquí) y utilícelas: no intente y haga coincidir la versión de Python, no está usando Python. –

+0

estoy de acuerdo con Lattyware. Si desea usar BeautifulSoup desde C#, ¿no podría simplemente ejecutarlo a través de IronPyhon? – mata

+0

¿No es esto para lo que es XPath? –

Respuesta

1

¿Has intentado ejecutar tu código dentro del motor de IronPython? Por lo que sé, funciona muy bien y no tienes que tocar tu código python.

+1

Esta es una gran idea; sin embargo, me gustaría ver un ejemplo de cómo se vería en C# para llamar a un método implementado en Python con parámetros nombrados. ¿IronPython proporciona una historia de interoperabilidad para este escenario? Además, hacer esto básicamente lleva esta pregunta a "¿Cómo uso una biblioteca de Python en .NET?" que no es realmente lo que estaba preguntando. –

Cuestiones relacionadas