#c# #asp.net #xpath #web-scraping #html-agility-pack
#c# #asp.net #xpath #веб-очистка #html-agility-pack
Вопрос:
Я создаю скребок для использования на многих сайтах (слишком много, чтобы очистить вручную с помощью инструмента веб-очистки, такого как Octoparse).
Каждый сайт, вероятно, будет отличаться по структуре. На некоторых сайтах могут быть данные, которые я хочу очистить; некоторые могут и не быть. Это должно быть определено с помощью списка ключевых слов / ключевых фраз. Сайты, которые я хочу, чтобы данные были проанализированы, они, вероятно, будут представлены в виде списка каким-либо образом. Однако элементы HTML, используемые для представления списка, не определены (т. Е. Могут быть списком ul, списком li, списком div, таблицей и т. Д.).
Если найдено ключевое слово / ключевая фраза, я хочу, чтобы был проанализирован не только этот элемент, но и все остальные, которые могут быть частью того же списка / группы.
Пример 1
<div>
<h1>Random content I am not interested in</h1>
</div>
<div>
<h1>Some more random content I am not interested in</h1>
</div>
<div>
<ul>
<li>Dogs</li>
<li>Cats</li>
<li>Birds</li>
</ul>
</div>
Пример 2
<div>
<h1>Random content I am not interested in</h1>
</div>
<div>
<h1>Some more random content I am not interested in</h1>
</div>
<div>
<div>
<div>
<div>
<h1>Bob</h1>
<p>A description of Bob</p>
</div>
<div>
<h1>Ben</h1>
<p>A description of Ben</p>
</div>
<div>
<h1>Bill</h1>
<p>A description of Bill</p>
</div>
</div>
</div>
</div>
Из первого примера, если бы я определил элемент Dogs
, я бы хотел, чтобы результат был Dogs, Cats, Birds
.
Из второго примера, если бы я определил Ben, я бы хотел, чтобы результатом было 3 элемента div, каждый из которых содержит заголовок и абзац; ключ в том, что все результаты должны включать HTML, а не только текст.
Любая помощь / рекомендации будут высоко оценены.
Комментарии:
1. Ваше описание желаемого результата несколько сбивает с толку; можете ли вы предоставить фактические результаты для этих двух примеров?
2. Похоже, вы ищете какое-то пользовательское решение NLP
Ответ №1:
Мне удалось что-то вроде этого:
static IEnumerable<string> FindSimilarItems(string html, string[] values, int maxDepth)
{
var doc = new HtmlDocument();
doc.LoadHtml(html);
var output = new List<string>();
foreach (var value in values)
{
var rootElement = doc.DocumentNode.SelectSingleNode($"//*[text()='{value}']");
if (rootElement == null) continue;
for (int i = 0; i < maxDepth; i )
{
var newXpath = RemoveXpathGroupIndex(rootElement.XPath, i);
var newElements = doc.DocumentNode.SelectNodes(newXpath);
if (newElements.Count <= 1) continue;
output.AddRange(newElements.Select(x => x.InnerText));
}
}
return output.GroupBy(x => x).Select(x => x.First()).ToList();
}
static string RemoveXpathGroupIndex(string xpath, int groupElement)
{
var splited = xpath.Split('/');
var pickedElement = splited.Length - 1 - groupElement;
splited[pickedElement] = splited[pickedElement].Substring(0, splited[pickedElement].IndexOf('['));
return string.Join("/", splited);
}
Этот код:
var similarItems = FindSimilarItems(input1, new string[] { "Dogs" }, 3);
Вернет
["Dogs", "Cats", "Birds"]