Iron Python,Beautiful Soup,Win32应用程序

21

美丽汤(Beautiful Soup)能在IronPython上工作吗?如果可以,需要使用哪个版本的IronPython? 使用IronPython(主要是C#调用一些Python代码来解析HTML),在.NET 2.0上分发Windows桌面应用程序有多容易?

10个回答

34
我曾经问过自己同样的问题,苦于在这里和其他地方遵循建议,使IronPython和BeautifulSoup能够与我的现有代码完美结合,我决定寻找一种替代的本机.NET解决方案。 BeautifulSoup是一段很棒的代码,起初似乎没有任何可用于.NET的类似内容,但后来我发现了HTML Agility Pack,如果说有什么不同,那就是我觉得它比BeautifulSoup更易于维护。它可以处理干净或混乱的HTML,并从中生成一个优雅的XML DOM,可以通过XPath进行查询。只需要几行代码,甚至可以获得原始的XDocument,然后使用LINQ to XML来构建查询。老实说,如果网页抓取是您的目标,那么这可能是您能找到的最干净的解决方案。

编辑

下面是一个简单的(读:一点也不健壮)示例,用于解析美国众议院的假日安排:

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();
        }
    }
}

HAP是一个很好的解决方案,我已经在生产中使用了一堆应用程序。我曾经使用过Mozilla Html解析器,两者之间没有太大的区别。 - Scott Cowan

8

我已经在IPy 1.1和2.0上测试并使用了BeautifulSoup(忘记是哪个beta版,但这是几个月前的事了)。如果您仍然遇到问题,请留下评论,我会找出我的测试代码并发布它。


5
如果BeautifulSoup在IronPython上无法工作,则是因为IronPython没有实现整个Python语言(与CPython相同)。 BeautifulSoup是纯Python编写的,没有C扩展,因此唯一的问题是IronPython与CPython在Python源代码方面的兼容性。不应该有问题,但如果有问题,错误将是显而易见的(“没有模块命名...”,“没有方法命名...”等)。谷歌说BS的测试中只有一个在IronPython上失败。它可能可以工作,并且该测试现在可能已经修复了。除非有更具体的建议,否则我建议您尝试一下。

2

另外,关于之前的一个评论,关于使用-X:SaveAssemblies编译的做法是错误的。-X:SaveAssemblies是作为调试特性存在的。有一种API用于将Python代码编译成二进制文件。 这篇文章解释了API以及两种模式之间的区别。


1

看起来使用IronPython 2.7没问题。只需要指向正确的文件夹,就可以开始了:

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'

1
关于您问题的第二部分,您可以使用DLR Hosting API在C#应用程序中运行IronPython代码。 DLR hosting规范在这里。 这个博客也包含一些示例托管应用程序。

1

我们正在分发一个由40k行IronPython应用程序组成的项目。我们无法将整个项目编译为单个可分发的二进制文件。相反,我们将其作为无数个小的dll文件进行分发,每个IronPython模块对应一个dll文件。虽然这种方式运行良好。

然而,在新版本IronPython 2.0中,我们最近发现可以将所有内容编译为单个二进制文件。这也导致应用程序启动更快(模块导入速度更快)。希望这个功能在未来几天内能够迁移到我们的主要项目中。

为了进行分发,我们使用WiX,这是微软内部用于创建msi安装程序的工具,已经开源(或至少免费提供)。尽管我们的安装有一些相当棘手的要求,但它并没有给我们带来任何问题。我肯定会考虑在将来使用WiX来分发其他IronPython项目。


0

我没有测试过,但我认为最新的IPy2应该可以使用。

至于分发,非常简单。使用 -X:SaveAssemblies 选项将您的Python代码编译成二进制文件,然后与其他DLL和IPy依赖项一起发送即可。


0

是的,这是可能的。 我正在使用ironpython v3.4.0与最新版本的bs4(v4.12.2)和soupsieve(v2.4.1)。

bs4soupsieve文件夹从您的cpython环境复制到您的{IPYTHON_DIR}/lib/site-packages文件夹中。或者,您可以将它们放在其他地方,并调用sys.path.append()来添加该目录。

编辑bs4\builder\_lxml.py并注释掉以下行:

        # if len(markup) > 0 and markup[0] == u'\N{BYTE ORDER MARK}':
        #   markup = markup[1:]

如果有人知道如何使上面的代码片段与ipython 3.4兼容,请提出修改建议。
现在,启动您的ipy控制台...
import bs4, soupsieve as sv

text = """<div><!-- These are animals --><p class="a">Cat</p><p class="b">Dog</p><p class="c">Mouse</p></div>"""
bs = bs4.BeautifulSoup(text)

bs.select('p:is(.a, .b, .c)')
bs.select_one('p:is(.a, .b, .c)')

sv.select('p:is(.a, .b, .c)', bs)
sv.select_one('p:is(.a, .b, .c)', bs)

-2

如果你有完整的标准库和真正的re模块(可以在IronPython社区版中搜索),它可能会起作用。但是IronPython是一个非常糟糕的Python实现,我不会指望它。

此外,试试html5lib。该解析器使用与Firefox解析文档相同的规则进行解析。


我不使用IronPython,但是我目前所了解的关于它的信息并没有证明它是“极差的Python实现”[已更正错别字]。 - tzot
我并不认为IronPython非常糟糕。它在许多方面表现得很好。只是不要指望它可以完全替代CPython。 - Jeff Brown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接