2008-09-23 20 views
21

¿Funciona la sopa hermosa con iron python? Si es así, ¿con qué versión de iron python? ¿Qué tan fácil es distribuir una aplicación de escritorio de Windows en .NET 2.0 usando iron python (principalmente C# llamando a algún código python para analizar html)?Iron python, sopa hermosa, aplicación win32

Respuesta

34

Me estaba haciendo esta misma pregunta y después de luchar para seguir los consejos aquí y en otros lugares para hacer que IronPython y BeautifulSoup jueguen bien con mi código existente, decidí ir a buscar una solución .NET nativa alternativa. BeautifulSoup es un código maravilloso y al principio no parecía que hubiera nada comparable disponible para .NET, pero luego encontré el HTML Agility Pack y, en todo caso, creo que en realidad obtuve más mantenimiento que BeautifulSoup. Toma HTML limpio o crujiente y produce un DOM XML elegante que se puede consultar a través de XPath. Con un par de líneas de código, incluso puede recuperar un XDocument sin procesar y luego craft your queries in LINQ to XML. Honestamente, si su objetivo es raspar la tela, esta es la solución más limpia que probablemente encuentre.

Editar

Aquí es un simple (es decir: no es robusto en absoluto) ejemplo que analiza la Cámara de Representantes de programación para las vacaciones:

using System; 
using System.Collections.Generic; 
using HtmlAgilityPack; 

namespace GovParsingTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      HtmlWeb hw = new HtmlWeb(); 
      string url = @"http://www.house.gov/house/House_Calendar.shtml"; 
      HtmlDocument doc = hw.Load(url); 

      HtmlNode docNode = doc.DocumentNode; 
      HtmlNode div = docNode.SelectSingleNode("//div[@id='primary']"); 
      HtmlNodeCollection tableRows = div.SelectNodes(".//tr"); 

      foreach (HtmlNode row in tableRows) 
      { 
       HtmlNodeCollection cells = row.SelectNodes(".//td"); 
       HtmlNode dateNode = cells[0]; 
       HtmlNode eventNode = cells[1]; 

       while (eventNode.HasChildNodes) 
       { 
        eventNode = eventNode.FirstChild; 
       } 

       Console.WriteLine(dateNode.InnerText); 
       Console.WriteLine(eventNode.InnerText); 
       Console.WriteLine(); 
      } 

      //Console.WriteLine(div.InnerHtml); 
      Console.ReadKey(); 
     } 
    } 
} 
+0

HAP es una buena solución, tengo un montón de aplicaciones en producción usándola. He usado Mozilla Html Parser y no hay mucha diferencia. –

0

No lo he probado, pero diría que probablemente funcione con el último IPy2.

En cuanto a la distribución, es muy simple. Use la opción -X: SaveAssemblies para compilar su código Python en un archivo binario y luego enviarlo con sus otras DLL y las dependencias IPy.

5

Si BeautifulSoup no funciona en IronPython, es porque IronPython no implementa todo el lenguaje Python (de la misma manera que CPython). BeautifulSoup es pure-python, no tiene C-extensions, por lo que el único problema es la compatibilidad de IronPython con CPython en términos de código fuente de Python. No debería haber ninguno, pero si lo hay, el error será obvio ("sin módulo named ... "," no method named ... ", etc.). Google dice que solo una de las pruebas de BS falla con IronPython. probablemente funcione, y esa prueba ya puede ser arreglada. No lo sabría

Pruébelo y vea, sería mi consejo, a menos que alguien tenga algo más concreto.

8

He probado y usado BeautifulSoup con ambos, IPy 1.1 y 2.0 (olvídate de la versión beta, pero esto fue hace unos meses). Deja un comentario si sigues teniendo problemas y voy a desenterrar mi código de prueba y publicarlo.

-2

Si tiene la biblioteca estándar completa y el módulo real re (google for IronPython community edition) podría funcionar. Pero IronPython es una increíble implementación de Python, no contaría con eso.

Además, pruebe html5lib. Ese analizador analiza con las mismas reglas que Firefox analiza documentos.

+0

No consumo IronPython, pero lo que he leído hasta ahora sobre ello no certifica la "aplicación muy mala pitón" [typo fijo ] – tzot

+0

Ciertamente no considero que IronPython sea increíblemente malo. Lo hace muy bien en un montón de cosas. Simplemente no espere que sea un reemplazo directo para CPython. –

1

Respecto a la segunda parte de su pregunta, puede usar las API de alojamiento de DLR para ejecutar el código de IronPython desde una aplicación C#. La especificación de alojamiento DLR es here. Este blog también contiene algunas aplicaciones de hospedaje de muestra

2

Además, en relación con uno de los comentarios anteriores sobre la compilación con -X: SaveAssemblies, eso es incorrecto. -X: SaveAssemblies se entiende como una función de depuración. Hay una API para compilar código python en binarios. This post explica la API y la diferencia entre los dos modos.

1

Estamos distribuyendo una aplicación IronPython 40k línea . No hemos podido compilar todo en una única distribución binaria. En cambio, hemos estado distribuyéndolo en un billón de dlls pequeños, uno para cada módulo de IronPython. Esto funciona bien sin embargo.

Sin embargo, en la versión más reciente, IronPython 2.0, tenemos un aumento reciente que parece ser capaz de compilar todo en un solo archivo binario. Esto también da como resultado una puesta en marcha más rápida de la aplicación (la importación de módulos es más rápida). Con suerte, este aumento migrará a nuestro árbol principal en los próximos días.

Para hacer la distribución, utilizamos WiX, que es una herramienta interna de Microsoft para crear instalaciones de msi, que ha sido de código abierto (o está disponible libremente, al menos). No nos ha dado ningún problema, aunque nuestro la instalación tiene algunos requisitos bastante complicados. Definitivamente consideraré usar WiX para distribuir otros proyectos de IronPython en el futuro.

1

Parece que funciona bien con IronPython 2.7. Sólo tiene que apunte a la carpeta correcta y ya está:

D:\Code>ipy 
IronPython 2.7 (2.7.0.40) on .NET 4.0.30319.235 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys 
>>> sys.path.append("D:\Code\IronPython\BeautifulSoup-3.2.0") 
>>> import urllib2 
>>> from BeautifulSoup import BeautifulSoup 
>>> page = urllib2.urlopen("http://www.example.com") 
>>> soup = BeautifulSoup(page) 
<string>:1: DeprecationWarning: object.__new__() takes no parameters 
>>> i = soup('img')[0] 
>>> i['src'] 
'http://example.com/blah.png' 
Cuestiones relacionadas