【发布时间】:2010-09-12 05:32:23
【问题描述】:
美丽的汤和铁蟒一起用吗? 如果是这样,使用哪个版本的铁蟒? 使用 Iron python 在 .net 2.0 上分发 Windows 桌面应用程序有多容易(主要是 c# 调用一些 python 代码来解析 html)?
【问题讨论】:
标签: .net python ironpython
美丽的汤和铁蟒一起用吗? 如果是这样,使用哪个版本的铁蟒? 使用 Iron python 在 .net 2.0 上分发 Windows 桌面应用程序有多容易(主要是 c# 调用一些 python 代码来解析 html)?
【问题讨论】:
标签: .net python ironpython
我也在问自己同样的问题,在努力遵循这里和其他地方的建议以使 IronPython 和 BeautifulSoup 与我现有的代码很好地配合之后,我决定寻找一个替代的原生 .NET 解决方案。 BeautifulSoup 是一段很棒的代码,起初它看起来没有任何可用于 .NET 的可比较的东西,但后来我找到了HTML Agility Pack,如果有的话,我认为我实际上已经获得了比 BeautifulSoup 的一些可维护性。它采用干净或粗糙的 HTML 并从中生成优雅的 XML DOM,可以通过 XPath 进行查询。使用几行代码,您甚至可以取回原始 XDocument,然后返回 craft your queries in 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();
}
}
}
【讨论】:
我已经在 IPy 1.1 和 2.0 中测试并使用了 BeautifulSoup(忘记了哪个测试版,但这是几个月前的事了)。如果您仍然遇到问题,请发表评论,我会挖掘我的测试代码并发布它。
【讨论】:
如果 BeautifulSoup 不能在 IronPython 上运行,那是因为 IronPython 没有实现整个 Python 语言(与 CPython 相同)。 BeautifulSoup是pure-python,没有C-extensions,所以唯一的问题是IronPython与CPython在Python源代码方面的兼容性。应该没有,但如果有,错误会很明显(“没有模块命名为 ...”、“没有命名为 ... 的方法”等)。谷歌表示只有 BS 的一项测试在 IronPython 上失败了。它可能有效,并且该测试现在可能已修复。我不知道。
试试看,这是我的建议,除非有人有更具体的建议。
【讨论】:
另外,关于以前的一个关于使用 -X:SaveAssemblies 编译的 cmets - 这是错误的。 -X:SaveAssemblies 是一种调试功能。有一个 API 用于将 python 代码编译成二进制文件。 This post解释了API以及两种模式的区别。
【讨论】:
我们正在分发一个 40k 行的 IronPython 应用程序。我们还不能将整个东西编译成一个二进制可分发文件。取而代之的是,我们一直将它作为无数个微小的 dll 分发,每个 IronPython 模块一个。不过这很好用。
但是,在较新的版本 IronPython 2.0 中,我们最近出现了一个峰值,它似乎能够将所有内容编译成一个二进制文件。这也导致应用程序启动速度更快(模块导入速度更快。)希望这个峰值将在接下来的几天内迁移到我们的主树中。
我们使用 WiX 进行分发,它是 Microsoft 用于创建 msi 安装的内部工具,它已经开源(或至少免费提供)。它没有给我们带来任何问题,即使我们的安装有一些相当繁琐的要求。将来我一定会考虑使用 WiX 分发其他 IronPython 项目。
【讨论】:
似乎与 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'
【讨论】:
我尚未对其进行测试,但我认为它很可能适用于最新的 IPy2。
至于分发,非常简单。使用 -X:SaveAssemblies 选项将 Python 代码编译为二进制文件,然后将其与其他 DLL 和 IPy 依赖项一起发布。
【讨论】:
如果您拥有完整的标准库和真正的 re 模块(Google for IronPython 社区版),它可能会起作用。但是 IronPython 是一个非常糟糕的 Python 实现,我不会指望它。
另外,试试html5lib。该解析器使用与 firefox 解析文档相同的规则进行解析。
【讨论】: