2012-05-03 2 views
5

Я изучаю возможность переноса библиотеки Python Beautiful Soup на .NET. В основном, потому что мне очень нравится синтаксический анализатор, и в .NET Framework нет хороших HTML-парсеров (Html ​​Agility Pack устарел, глючит, недокументирован и не работает хорошо, если не известна точная схема.)Портирование библиотеки Pythonesque на .NET.

Один из мои основные цели - получить базовую функциональность выбора DOM, чтобы действительно сравнить красоту и простоту BeautifulSoup, позволяя разработчикам легко создавать выражения для поиска элементов, которые они ищут.

BeautifulSoup использует преимущества несвязанных и названных параметров, чтобы это произошло. Например, чтобы найти все a тегов с id из test и title, который содержит слово Foo, я мог бы сделать:

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

Однако C# не имеет понятия произвольного числа по имени элементы. Время выполнения .NET4 имеет именованные параметры, однако они должны соответствовать существующему прототипу метода.

Мой вопрос: Что такое шаблон дизайна C#, который наиболее параллелен этой конструкции Pythonic?

Некоторые идеи:

Я хотел бы пойти после того, как это основано на том, как я, как разработчик, хотел бы кодировать. Реализация этого выходит за рамки этой публикации. Одна из моих идей - использовать анонимные типы. Что-то вроде:

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

Хотя этот синтаксис не соответствует реализации Python, он по-прежнему имеет некоторые недостатки.

  1. Реализация FindAll должна будет использовать отражение для анализа анонимного типа и надлежащим образом обрабатывать любые произвольные метаданные.
  2. Для прототипа FindAll необходимо принять Object, что делает его довольно неясным, как использовать этот метод, если вы не хорошо знакомы с документированным поведением. Я не верю, что есть способ объявить метод, который должен использовать анонимный тип.

Еще одна идея, которая у меня была, - это, пожалуй, более простой способ обработки, но отступает от корней 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#, или просто общие рекомендации по наилучшим образом справиться с этой ситуацией.

+7

Насколько я люблю Python - всегда обращайтесь к аудитории, которая будет ее использовать. Если вы пишете его для .NET, сделайте это в том стиле, который они используют. Посмотрите на существующие библиотеки .NET и посмотрите, что это за практика (или подождите, пока кто-то скажет вам об этом), и используйте их - не пытайтесь сопоставить версию Python, вы не используете Python. –

+0

Я согласен с Lattyware. Если вы хотите использовать BeautifulSoup с C#, не могли бы вы просто запустить его через IronPyhon? – mata

+0

Разве это не XPath? –

ответ

1

Вы пытаетесь запустить свой код внутри движка IronPython. Насколько я знаю, это очень хорошо работает, и вам не нужно прикасаться к вашему коду python.

+1

Это отличная идея, однако я хотел бы увидеть пример того, как было бы выглядеть в C# для вызова метода Python с именованными параметрами. Предоставляет ли IronPython историю взаимодействия для этого сценария? Кроме того, это в основном направляет этот вопрос на вопрос «Как использовать библиотеку Python в .NET?» на самом деле это не то, о чем я просил. –

Смежные вопросы