Я изучаю возможность переноса библиотеки 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, он по-прежнему имеет некоторые недостатки.
- Реализация
FindAll
должна будет использовать отражение для анализа анонимного типа и надлежащим образом обрабатывать любые произвольные метаданные. - Для прототипа
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#, или просто общие рекомендации по наилучшим образом справиться с этой ситуацией.
Насколько я люблю Python - всегда обращайтесь к аудитории, которая будет ее использовать. Если вы пишете его для .NET, сделайте это в том стиле, который они используют. Посмотрите на существующие библиотеки .NET и посмотрите, что это за практика (или подождите, пока кто-то скажет вам об этом), и используйте их - не пытайтесь сопоставить версию Python, вы не используете Python. –
Я согласен с Lattyware. Если вы хотите использовать BeautifulSoup с C#, не могли бы вы просто запустить его через IronPyhon? – mata
Разве это не XPath? –