Проблема с форматированием текста в appleScript. - PullRequest
1 голос
/ 14 марта 2020

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

7:00
Name of Meeting: Location Bad
Address
Area
8:00
Name of Meeting: Location Good
Address
Area
Noon
Name of Meeting: Location Good 2
Address
Area
3:00 pm
Name of Meeting: Location Bad 2
Area

Моя цель состоит в том, чтобы извлечь все собрания в определенных местах (Расположение хорошее и Расположение хорошее 2). Идеально фильтруя только эту информацию -> Время @ Местоположение Хорошо, Время @ Местоположение Хорошо 2.

Я не знаю, как отформатировать текст, чтобы сделать это. Я попытался отфильтровать его, но, поскольку вся информация разделена на разные строки, фильтр возвращается как ключевое слово, которое я фильтрую (используя Automator). Чтобы обойти это, я просто сделал это вручную и настроил яблочный скрипт для отправки мне текстового сообщения с информацией, которую я уже отфильтровал вручную. Пока это работает, но когда информация на сайте изменится, моя информация устареет.

Вот сайт: https://loukyaa.org/meetings/?tsml-day=6&tsml-region=louisville

Вопрос: как мне манипулировать текстом, чтобы отфильтровать информацию, которую я хочу? Я заинтересован в фильтрации всех встреч для «Ледхауса» и «Клуба Token 3». Спасибо!

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

@ user3439894 - отличный ответ, и он показал вам несколько хороших и надежных методов определения загрузки веб-страницы; некоторый элементарный JavaScript; и сила awk.

Я решил сделать это по-другому. Я использую JavaScript для выполнения всей тяжелой обработки, в основном потому, что моей конечной целью было получение списка record объектов, каждый из которых представлял одно событие, указанное на веб-странице, из которого я извлек имя, местоположение и время каждого event.

tell application id "com.apple.Safari" to tell ¬
    document 1 to set allEvents to do JavaScript ¬
    "Array.from(document
               .querySelectorAll('tbody#meetings_tbody '+
                                'tr '+
                                'td.name,'+
                                'td.time,'+
                                'td.location'))
               .reduce((ξ,x,i,L) => { 
                        ξ=Array.from(ξ);
                        i%3==1 && ξ.push({
                                'name': L[i].innerText,
                                'time': L[i-1].innerText,
                                'location': L[i+1].innerText
                        }); 
                        return ξ;
               });"

Переменная allEvents должна содержать что-то вроде этого:

{{|name|:"Saturday @ 7", |time|:"7:00 am", location:"Token 3 Club"},
 {|name|:"Early Bird Meeting", |time|:"8:00 am", location:"Token 3 Club"},
 {|name|:"Saturday Morning Meditation Group", |time|:"8:30 am", location:"Christ Church United Methodist"},
 {|name|:"Saturday Morning Gratitude Group", |time|:"8:30 am", location:"Icehouse"},
 ...,
 {|name|:"Agape", |time|:"10:30 pm", location:"Token 3 Club"}}

Я не уверен, насколько вы знакомы с AppleScript list или record объекты. Если вы внимательно изучите содержимое, вы увидите, что каждое событие представлено объектом, который выглядит следующим образом:

{|name|:"...", |time|:"...", location:"..."}

Это record, который содержит три properties: |name|, |time| и location. Каждый property имеет значение, которое вы получаете, ссылаясь на <property> of <record>. Таким образом, если создать объект записи и назначить его переменной следующим образом:

set R to {a:1, b:"two", c:pi}

, то:

set myvar to b of R

извлечет значение свойства b, принадлежащее записи R и сохраните его в переменной myvar. Таким образом, myvar теперь оценивается как "two".

allEvents - это не просто один record объект; это много. Это list из них. Вот пример списка:

set L to {1, "two", pi, 2^2, "5.0"}

Это не содержит свойства; он содержит только значения, и они называются items. list проводится в строгом порядке, а record - нет. Следовательно, значение "two" будет всегда появляться как второе item в этом списке, но в записи оно может появляться в начале, в середине или в конце, но всегда будет присоединено к свойство b. Чтобы извлечь элемент из списка:

set myvar to item 2 of L

Итак, несколько пропустив до конца, если вы хотите определить местоположение 4-го события в этом списке:

return the location of item 4 in allEvents --> "Icehouse"

все еще хотите последовать примеру @ user3439894 и реализовать тест, чтобы определить, когда страница загрузилась (если вы не собираетесь запускать скрипт вручную только после загрузки страницы самостоятельно). @ user3439894 также показал вам, как адаптировать код для браузера на основе Chromium (Google Chrome, Vivaldi, Brave).

0 голосов
/ 15 марта 2020

С неполной информацией, представленной в вашем вопросе, позвольте мне предложить решение для Safari и Google Chrome, чтобы открыть цель URL в новом окне , используйте JavaScript, чтобы получить внутренний текст к таблице , закройте окно и отфильтруйте его в виде Время @ Местоположение , например 7: 00 am @ Token 3 Club , содержащее собрание время и местоположение для Ледяной домик и Клуб токенов 3 .

Использование JavaScript, в этом случае использования это возвращает абзацев текста с разделителями табуляции в переменной foo, которая будет отфильтрована с помощью awk в команде do shell script , где конечный результат равен хранится в переменной с именем bar, которую вы затем можете сделать с любым , с которым захотите.

Следующий пример AppleScript код * 105 6 * для Safari :

set theURL to "https://loukyaa.org/meetings/?tsml-day=6&tsml-region=louisville"

tell application "Safari" to make new document with properties {URL:theURL}

tell application "System Events"
    repeat until exists ¬
        (buttons of UI elements of groups of toolbar 1 of window 1 of ¬
            application process "Safari" whose name = "Reload this page")
        delay 0.5
    end repeat
end tell

tell application "Safari"
    set foo to do JavaScript ¬
        "document.getElementById('meetings_tbody').innerText;" in document 1
    close its front window
end tell

set awkCommand to ¬
    "awk 'BEGIN{FS=\"\t\"; OFS=\" @ \"}/Icehouse|Token 3 Club/{print $1,$3}'"

set bar to do shell script awkCommand & " <<< " & foo's quoted form
  • ПРИМЕЧАНИЕ: Этот код был протестирован под macOS Высокая Сьерра , однако, для macOS Mojave и более поздних версий, удалите слова buttons of из repeat until exists ¬ ... кода .

  • ПРИМЕЧАНИЕ: do JavaScript работает только , если Разрешить JavaScript от Apple Events проверено на Safari > Разработка меню, которое по умолчанию скрыто и может быть отображено путем проверки [√] Показать меню «Разработка» в строке меню в: Safari > Предпочтения… > Дополнительно


Следующий пример AppleScript код предназначен для Google Chrome:

set theURL to "https://loukyaa.org/meetings/?tsml-day=6&tsml-region=louisville"

tell application "Google Chrome"
    set URL of active tab of (make new window) to theURL
    repeat until (loading of tab 1 of window 1 is false)
        delay 0.5
    end repeat
    tell active tab of front window to set foo to ¬
        execute javascript ¬
            "document.getElementById('meetings_tbody').innerText;"
    close its front window
end tell

set awkCommand to ¬
    "awk 'BEGIN{FS=\"\t\"; OFS=\" @ \"}/Icehouse|Token 3 Club/{print $1,$3}'"

set bar to do shell script awkCommand & " <<< " & foo's quoted form

ПРИМЕЧАНИЕ: Это должно работать по умолчанию , как Google Chrome позволяет выполнять JavaScript.


В любом случае переменная bar содержит, например: * 11 31 *

7:00 am @ Token 3 Club
8:00 am @ Token 3 Club
8:30 am @ Icehouse
8:30 am @ Icehouse
10:30 am @ Icehouse
2:00 pm @ Token 3 Club
4:00 pm @ Token 3 Club
6:00 pm @ Icehouse
6:00 pm @ Icehouse
6:00 pm @ Token 3 Club
8:00 pm @ Icehouse
8:00 pm @ Token 3 Club
10:30 pm @ Token 3 Club

Затем вы можете делать с ним, как вы, sh.

Также обратите внимание, что FS=\"\t\"; часть awk команды будет расширена до обычный символ табуляции при компиляции, например, Редактор скриптов . Использование \t необходимо при публикации кода на этом сайте, в противном случае он будет отображаться как, например, FS=\" \";, а затем при копировании кода это не будет нормальным символ табуляции после компиляции.


Примечание: пример AppleScript код - это просто и не содержит никакой дополнительной обработки ошибок , которая может быть уместной. Пользователь должен добавить любую обработку ошибок , которая может быть уместной, необходимой или желаемой. Взгляните на оператор try и error оператор в Руководство по языку AppleScript . См. Также, Работа с ошибками . Кроме того, может потребоваться использование delay command между событиями, где это уместно, например, delay 0.5, со значением задержка установлена ​​соответствующим образом.

...