Предположим, вы используете привязки клиента Java для Selenium WebDriver и вам нужно извлечь содержимое очень большой таблицы.

Самый простой способ — найти WebElement и вызвать его метод getText. Это работает очень хорошо: быстро и показывает только видимый текст. У него есть один потенциальный недостаток: теряются различия между ячейками. Вам нужно разбить строку на строки и слова, чтобы восстановить явные различия:

Если в самих ячейках есть пробелы, синтаксический анализ становится более сложным.

Альтернативное решение — явно получить строки/ячейки с помощью findElementsByTagName, а затем вызвать getText для каждой конкретной ячейки, создавая в процессе список списков строк. Что-то типа:

Однако это ужасно медленно для больших таблиц! Причиной являются повторные вызовы isDisplayed и getText.

Как получить лучшее из обоих миров? RemoteWebDriver имеет универсальный метод executeJavascript, который выполняет множество автоматических операций сортировки между Java и Javascript. В частности, вы можете передавать объекты WebElement в качестве параметров из Java, и соответствующие DOM-элементы будут доступны в массиве arguments! То же самое и с результатами: если вы возвращаете вложенный массив строк из Javascript, он будет доступен в Java как вложенный список.

Итак, идея состоит в том, чтобы построить вложенный массив на стороне браузера и вернуть его в Java за один раз:

Этот подход, кажется, работает достаточно хорошо. Его скорость сравнима с исходным решением getText. В своем нынешнем виде у него есть недостаток, заключающийся в том, что он не проверяет видимость каждой отдельной ячейки. (Помните, что getText возвращает только видимое содержимое.)

Я реализовал три подхода в этом репозитории GitHub, который тестирует их на образце таблицы.