【问题标题】:Porting a very Pythonesque library over to .NET将一个非常 Pythonesque 的库移植到 .NET
【发布时间】:2012-05-03 15:57:29
【问题描述】:

我正在研究将 Python 库 Beautiful Soup 移植到 .NET 的可能性。主要是因为我真的很喜欢解析器,而且 .NET 框架上根本没有好的 HTML 解析器(Html Agility Pack 已经过时、有缺陷、没有文档,除非知道确切的架构,否则不能很好地工作。)

我的主要目标之一是让基本的 DOM 选择功能真正与 BeautifulSoup 的美感和简单性并驾齐驱,让开发人员能够轻松地制作表达式以找到他们正在寻找的元素。

BeautifulSoup 利用松散绑定和命名参数来实现这一点。例如,要查找所有idtest 和包含单词footitlea 标签,我可以这样做:

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

但是,C# 没有任意数量的命名元素的概念。 .NET4 运行时有命名参数,但是它们必须匹配现有的方法原型。

我的问题:与这种 Pythonic 构造最相似的 C# 设计模式是什么?

一些想法:

我想根据我作为开发人员的编码方式来解决这个问题。实现这一点超出了本文的范围。我的一个想法是使用匿名类型。比如:

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

虽然这种语法与 Python 实现松散匹配,但它仍然有一些缺点。

  1. FindAll 实现必须使用反射来解析匿名类型,并以合理的方式处理任意元数据。
  2. FindAll 原型需要采用Object,这使得除非您非常熟悉记录的行为,否则不清楚如何使用该方法。我不相信有办法声明一个必须采用匿名类型的方法。

我的另一个想法可能是一种更 .NET 的方式来处理这个问题,但离库的 Python 根源更远。那将是使用流利的模式。比如:

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

这需要构建一个表达式树并在 DOM 中定位适当的节点。

我的第三个也是最后一个想法是使用 LINQ。比如:

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

如果任何有将 Python 代码移植到 C# 的经验的人提供任何见解,或者就处理这种情况的最佳方法提供总体建议,我将不胜感激。

【问题讨论】:

  • 尽管我很喜欢 Python - 始终瞄准会使用它的受众。如果您正在为 .NET 编写它,请按照他们使用的样式进行。查看现有的 .NET 库,看看实践是什么(或在这里等待有人告诉你)并使用它们 - 不要尝试匹配 Python 版本,你没有使用 Python。
  • 我同意 Lattyware。如果你想在 C# 中使用 BeautifulSoup,你不能只通过 IronPyhon 运行它吗?
  • 这不是 XPath 的用途吗?
  • @Lattyware - 是的,我的一部分只是说 搞砸 并想简单地为 .NET 编写最好的 DOM 解析器。它在很大程度上受到了 BeautifulSoup 的启发,但绝不是一个端口。我还考虑将这个库编写为 AgilityPack 的一组扩展方法,这也许也是一种方法。
  • @mata - 首先,我想知道让 BeautifulSoup 在 IronPython 下编译会有多难。其次,我想知道 C# 代码和 Python 代码之间的互操作如何工作。我对 IronPython 的了解还不够,无法回答这个问题。

标签: c# python beautifulsoup


【解决方案1】:

您是否尝试在 IronPython 引擎中运行您的代码。据我所知,性能非常好,您不必触摸您的 python 代码。

【讨论】:

  • 这是个好主意,但是我想看看在 C# 中调用带有命名参数的 Python 实现方法的示例。 IronPython 是否为此场景提供了互操作故事?此外,这样做基本上将这个问题引向“如何在 .NET 中使用 Python 库?”这不是我真正要问的。
猜你喜欢
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多