5

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

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

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

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# 经验的人的任何见解,或者只是关于处理这种情况的最佳方法的总体建议。

4

1 回答 1

1

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

于 2012-05-03T16:05:00.990 回答