Как выбрать все теги, кроме якорей (ни якорей внутри другого элемента) с document.querySelectorAll? - PullRequest
1 голос
/ 14 октября 2019

edit : возможно ли получить весь внутренний текст из тегов в HTML-документе, кроме текста из тегов привязки <a> (ни текста из <a> привязок внутридругие элементы) с помощью метода document.querySelectorAll?

Моя программа имеет поле ввода, которое позволяет пользователям вставлять некоторые селекторы, чтобы получить текст для определенных тегов на данной странице сайта. Итак, если я хочу вставить селектор, который получает текст со всех узлов, кроме тегов <a>, как я могу это сделать? Я имею в виду *:not(a) не работает, потому что он выбирает теги, которые могут иметь <a> потомков, а not() селектор не принимает сложные селекторы, поэтому *:not(* a) не работает.

Я знаюЯ мог бы сначала удалить эти узлы из документа , , но можно ли выполнить эту задачу, выбрав только те узлы, которые я хочу, с помощью метода document.querySelectorAll? Пример:

<html>
  <... lots of other tags with text inside>
    <div>
      <p> one paragraph </p>
      <a> one link </a>
    </div>
  </...>
</html>

Я хочу, чтобы весь текст в html, кроме "одна ссылка"

edit: Если вы делаете document.querySelectorAll('*:not(a)'), вы выбираете div, который имеет внутри a элемент. Итак, внутренний текст этого div содержит текст из a элемента

Спасибо

Ответы [ 4 ]

3 голосов
/ 14 октября 2019

Ваш вопрос заключается в том, как разрешить пользователям извлекать информацию из произвольного гипертекста [документы]. Это означает, что решение проблемы «какие элементы очистить» - это всего лишь часть этого. Другая часть - «как преобразовать набор элементов в набор данных, который в конечном счете заинтересован пользователем».

Это означает, что CSS-селекторы сами по себе не подойдут. Вам необходимо преобразование данных, которое будет иметь дело с набором элементов в качестве входных данных и выдаст интересующий набор данных в качестве выходных данных. В вашем вопросе это проиллюстрировано на примере того, что вам просто нужно текстовое содержимое некоторых элементов или всего документа, но как если бы элементов a не было. Это ваша процедура преобразования в данном конкретном случае.

Однако вы заявляете, что хотите разрешить пользователям указывать, что они хотят очистить. Это означает, что ваша процедура преобразования имеет другие переменные и, возможно, является общей по отношению к типу преобразований, которые она может выполнять.

Учитывая это, я бы посоветовала вам взглянуть на такие технологии, как XSLT ,XSLT, с одной стороны, предназначен для этих вещей - преобразования данных.

В зависимости от того, насколько компьютерным вы считаете, что ваши пользователи ожидают, вам может потребоваться инкапсулировать всю мощь и сложность XSLT, предоставляя пользователям простоеПользовательский интерфейс, который переводит их запросы в XSLT и затем передает полученные таблицы стилей XSL, например, в процессор XSLT. В любом случае, сам XSLT сможет нести большую нагрузку. Вам также не понадобятся CSS-селекторы XSLT и - первый использует XPath, который вы можете использовать и даже предоставлять пользователям.

Давайте рассмотрим следующий короткий пример HTML-документа, который выwant scraped:

<html>
    <body>
        <p>I think the document you are looking for is at <a href="example.com">example.com</a>.</p>
    </body>
</html>

Если вы хотите извлечь весь текст, но не элементы a, следующая таблица стилей XSL настроит процессор XSLT для получения именно этого:

<?xml version="1.0" encoding="utf-8" ?>
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <output method="text" />
    <template match="a" /><!-- empty template element, meaning that the transformation result for every 'a' element is empty text -->
</stylesheet>

Результатпреобразования документа HTML с помощью вышеуказанного документа таблицы стилей XSL - это следующий текст:

Я думаю, что документ, который вы ищете, находится в.

Обратите внимание, как a элемент "обрезается", оставляя пустое пространство между "at" и пунктуацией предложения (.). Элемент template, будучи пустым, настраивает процессор XSLT так, чтобы он не выдавал никакого текста при преобразовании элементов a (кстати, "a" является допустимым, хотя и очень простым выражением XPath - он выбирает все aэлементы). Конечно, это все часть XSLT.

Я проверил это с Бесплатный онлайн XSL Transformer , который использует очень мощную библиотеку SAX.

Конечно, вы можетеохватить один конкретный вариант использования - ваш - с помощью JavaScript, без XSLT. Но как вы собираетесь позволить своим пользователям выражать то, что они хотят, чтобы их убрали? Вам, вероятно, придется изобрести какой-нибудь [простой] язык - который в любом случае может также включать XSLT.

XSLT не всегда доступен для различных пользовательских агентов или сред выполнения JavaScript, не из коробки - нативный XSLTРеализации 1.0 действительно предусмотрены как Firefox, так и Chrome (с классом XSLTProcessor), но не определены ни одним органом стандартизации и поэтому могут отсутствовать в вашей конкретной среде выполнения. Возможно, вы сможете найти подходящую реализацию JavaScript, но в любом случае вы можете вызвать скребок на стороне сервера.

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

1 голос
/ 14 октября 2019

верхний узел клона, удалите a s из клона, получите текст.

const bodyClone = document.body.cloneNode(true);
bodyClone.querySelectorAll("a").forEach(e => e.remove());
const { textContent } = bodyClone;
0 голосов
/ 14 октября 2019

вы можете использовать

document.querySelectorAll('*:not(a)')

надеюсь, что это сработает.

0 голосов
/ 14 октября 2019
document.querySelectorAll('*:not(a)')
...