Я хочу очистить файл .mhtml с помощью bash, изначально я использовал только curl + xidel для очистки файла html, но теперь в Интернете есть «что-то», что мешает мне очищать.
это часть контента:
QuoteStrip-watchLiveLink">LIVE<img src=3D"https://static-redesign.cnbcfm.co=
m/dist/4db8932b7ac3e84e3f64.svg" alt=3D"Watch live logo" class=3D"QuoteStri=
p-watchLiveLogo"></a><a href=3D"https://www.cnbc.com/live-tv/" style=3D"col=
or: rgb(0, 47, 108);">SHARK TANK</a></div></div></div><div class=3D"QuoteSt=
rip-quoteStripSubHeader"><span>RT Quote</span><span> | <!-- -->Exchange</sp=
an><span> | <!-- -->USD</span></div><div class=3D"QuoteStrip-dataContainer"=
><div class=3D"QuoteStrip-lastTimeAndPriceContainer"><div class=3D"QuoteStr=
ip-lastTradeTime">Last | 11:46 PM EDT</div><div class=3D"QuoteStrip-lastPri=
ceStripContainer"><span class=3D"QuoteStrip-lastPrice">1,621.41</span><span=
class=3D"QuoteStrip-changeDown"><img class=3D"QuoteStrip-changeIcon" src=
=3D"https://static-redesign.cnbcfm.com/dist/4ee243ff052e81044388.svg" alt=
=3D"quote price arrow down"><span>-6.2537</span><span> (<!-- -->-0.3842%<!-=
- -->)</span></span></div></div></div></div><div class=3D"PhoenixChartWrapp=
вопрос:
Как я могу получить только 1,621.41
в качестве вывода в bash?
Моя обычная программа:
#!/bin/bash
curl -s -o ~/Desktop/xau.html -- https://www.cnbc.com/quotes/XAU=
gold=$(xidel -se /html/body/div[2]/div/div[1]/div[3]/div/div[2]/div[1]/div[2]/div[3]/div/div[2]/span[1] ~/Desktop/xau.html | sed 's/\,//g')
echo $gold
exit 0
вывод: некоторые числа
когда я использую XPATH, он всегда идет после тега lastPrice, и это что-то вроде /html/body/div[2]/div/div[1]/div[3]/div/div[2]/div[1]/div[2]/div[3]/div/div[2]/span[1]
для полного или //*[@id = "quote-page-strip"]/div[3]/div/div[2]/span[1]
что-то подобное оттуда, так я ищу значение
Итак, ваш вопрос сводится к следующему: как извлечь текст между двумя частями другого (фиксированного) текста. Это правильно? Я спрашиваю, потому что что-то вроде этого является несколько расплывчатым определением проблемы.
Извините, но строки кода, которые я предоставил, - это просто полоса от целого, я просто хочу сохранить ее в чистоте.
@ user1934428 вроде да, прежде чем я подумал, что перед этим «фиксированным» текстом есть другие случайные тексты, так что да, поэтому я изменил вопрос.
Не дав точного определения того, как разграничиваются искомые числа, нельзя рассчитывать найти алгоритм. Поскольку вы уже используете xpath, не можете ли вы извлечь его с помощью самого xpath?
Я сказал в своем вступлении, что «что-то» мешает мне использовать экстракт xpath, я думаю, что это похоже на что-то, исходящее от машины защиты от утилизации cloudflare.
Но вы можете загрузить документ, и вы установили xpath локально. Если файл является допустимым XML, что должно помешать вам его использовать? OTOH, если это html, вы можете использовать парсер для HTML ... возможно, через Node.js или Perl?
Я не знаю, он просто гаснет, когда я открываю файл, я не знаю, что не так. когда я пытался извлечь его, он возвращает ноль на bash. вчера все еще нормально, он возвращает некоторые числа.
Если файл пустой, конечно, вы ничего не сможете извлечь. Однако что вы подразумеваете под открытием файла? Я бы в первую очередь посмотрел файл с чем-то вроде xxd
, чтобы понять, что у вас есть. Может быть, ваша реальная проблема заключается не в получении информации из определенного файла, а в воспроизведении самого файла в определенном формате?
Я открыл html-файл в браузере, файл открывается нормально, даже без интернета. он открывается, показывая содержимое в течение 1 секунды, а затем переходит в "пустой белый холст"
его можно без проблем открыть в текстовой панели, но это просто текст, а не html, который нужно обрабатывать с помощью Xidel.
Я предполагаю, что textpad - это текстовый редактор, который вы используете. Итак, как же тогда выглядит текст?
@ user1934428 позвольте мне еще раз уточнить, моя обычная программа выглядит так: #!/bin/bash curl -s -o ~/Desktop/xau.html -- cnbc.com/quotes/XAU= gold=$( xidel -se "/html/body/div[2]/div/div[1]/div[3]/div/div[2]/div[1]/div[2]/div[3]/div /div[2]/span[1] ~/Desktop/xau.html" | sed 's/\,//g') echo $gold exit 0 можете попробовать
Одна трудность в том, что линии обрываются где угодно (=\n
). Сначала соедините строки, а затем извлеките то, что вы ищете:
$ sed -En ':a
s/=\n//g;s!.*<span class=3D"QuoteStrip-lastPrice">([^<]*)</span>.*!\1!p;tb
N;ba
:b
> q' file
1,621.41
Или с GNU sed
и его опцией -z
:
$ sed -Ez 's!=\n!!g;s!.*<span class=3D"QuoteStrip-lastPrice">([^<]*)</span>.*!\1!' file
1,621.41
Я получил этот результат sed: 1: "s/=\n//g;s!.*<span clas ...": undefined label 'a;N;b;:a;q'
Какую версию sed
вы используете?
версия для ОС
@foopeen: вы можете установить инструменты gnu и использовать gnu sed или адаптировать решение для BSD sed, которое вы, похоже, используете в настоящее время.
@foopeen: вы набрали первый скрипт sed
отдельными строками, как показано, или все в одной строке? Если второе, попробуйте скопировать-вставить именно из ответа. Я только что проверил под macOS, и он работает.
sed: illegal option -- z
из GNU sed
@RenaudPacalet ах, извините, я попробовал еще раз, на этот раз он работает, в той же ситуации, что и в «примере», который я предоставил, но он ничего не возвращает, когда я использовал его для полного файла.
Загрузил файл, размер 1,9M, drive.google.com/file/d/1TTKn_n00dVh2C5l5tVvztLKwzxEgNqyL/…
Я не пользуюсь гугл диском.
@RenaudPacalet извините, вот ссылка для скачивания file.io/VQY8NHmvzsCl
так как сэр @RenaudPacalet ответил на вопрос, который я начал, я отдаю вам должное за ответ на мой вопрос. Спасибо, мистер, хотя это не лучшее решение, я все же кое-что узнал о sed
Хорошо, с вашим полным примером я думаю, что понял, что не работает, и исправил это. Пожалуйста, попробуйте новую версию (но также рассмотрите возможность обновления утилиты sed
до лучшей версии, чем стандартная версия Apple).
Я использую curl+xidel только для очистки HTML-файла.
xidel
может без проблем открывать URL-адреса, поэтому curl
не нужен.
/html/body/div[2]/div/div[1]/div[3]/div/div[2]/div[1]/div[2]/div[3]/div/div[2]/span[1] ^
Этот конкретный div не существует. Здесь только один. Итак, это должно работать:
$ xidel -s "https://www.cnbc.com/quotes/XAU = " -e '
/html/body/div[2]/div/div[1]/div[3]/div/div/div[1]/div[2]/div[3]/div/div[2]/span[1]
'
Также, пожалуйста, не забудьте процитировать запрос на извлечение. Это предотвратит ситуации, когда в противном случае вам пришлось бы экранировать множество символов.
HTML-исходник сайта минимизирован. Чтобы иметь лучший обзор всех узлов HTML-элементов, я предлагаю вам снова украсить исходный код:
$ xidel -s "https://www.cnbc.com/quotes/XAU = " -e . \
--output-format=html --output-node-indent > ~/Desktop/xau.html
И таким образом вы можете видеть, что запрос можно упростить до:
$ xidel -s "https://www.cnbc.com/quotes/XAU = " -e '
//span[@class = "QuoteStrip-lastPrice"]
'
Или, альтернативно, из одного из JSON в <head>
-узле:
$ xidel -s "https://www.cnbc.com/quotes/XAU = " -e '
parse-json(//script[@type = "application/ld+json"][2])/price
'
насчет красивости, Error Unknown option: output-node-indent (when reading argument: output-node-indent) The following command line options are valid: --data= Data/URL/File/Stdin(-) to process (--data= prefix can be omitted) bla bla bla
На самом деле раньше я использовал только xidel
, я запускал его каждые x секунд, но иногда это вызывало проблемы, останавливался на полпути, поэтому мне приходилось нажимать ctrl+c и перезапускать скрипт bash. вот почему я предпочитаю загружать его и обрабатывать локально. Кстати, о This particular div doesn't exist. There's only one. So this should work:
Как вы узнали об этом? Я скопировал XPATH прямо из браузера Chrome, вы хотите сказать, что они меня обманывают?
по правде говоря, это то, что я ищу, но у меня все еще есть некоторые вопросы о том, почему это вдруг не работает «по-моему», я отвечу на это в другой теме. Я хочу отдать должное вашему ответу, но я все еще не могу этого сделать, извините.
@foopeen Я обнаружил это, украсив исходный HTML-код, как упоминалось выше. Я не пользуюсь Chrome, поэтому ничего не могу сказать по этому поводу. По поводу сообщения об ошибке: пожалуйста обновите до бинарника из ветки разработки v0.9.9.
поскольку именно вы решаете эту проблему, я думаю, вам следует пойти сюда и опубликовать свое решение, а также указать, какой инструмент вы использовали для обнаружения этой проблемы и тому подобного. Спасибо
@foopeen Мне казалось очевидным, что единственный инструмент, которым я пользуюсь, это xidel
. Опять же, я не использую Chrome, поэтому я не могу комментировать это или публиковать ответ. Кстати, вы говорите, что я решил вашу проблему, но вы приняли сомнительный sed
подход...
вам не нужно использовать хром, чтобы узнать XPATH HTML-файла, что «Chrome Elements Inpect» — это просто инструмент, вы можете открыть любой HTML-файл с помощью любого простого редактора, такого как редактор кода (возвышенный текст, например ), это неочевидно, потому что кажется скрытым. Единственное, что я вижу из структуры, это то, что ценник находится в теге div[2]. что касается принятого ответа, первоначальный вопрос касался извлечения информационного файла «mhtml», который содержит беспорядочную структуру и весит намного больше, чем обычный файл «html», если я приму ваш ответ, это смутит людей.
опять же, если я хочу, чтобы я принял ваш ответ, мне придется изменить весь вопрос, включая заголовок. извините, это лучшее, что я могу придумать.
Вы упомянули html prettify раньше, поэтому я попытался использовать этот способ. Вставил загруженный html-файл, украсил его и открыл с помощью Sublime Text. Я обнаружил, что div[1], который должен иметь <div class = "BadgeGroup-badgeGroup">...</div>
, не существует, вместо этого он стал местом <div class = "QuotePageBuilder-row">
....хм... теперь это становится проблемой, вопрос теперь изменен на "почему он исчез ?"
вы можете ответить на пост , если вы знаете, что происходит
Как вы визуально определяете эти числа внутри текста? Они всегда идут после
lastPrice">
и перед</span>
?