Precisa extrair um número do HTML

2

Dado isso:

<p>Currencies fluctuate every day. The rate shown is effective for transactions submitted to Visa on <strong>February 5, 2017</strong>, with a bank foreign transaction fee of <st <span><strong>1</strong> Euro = <strong>1.079992</strong> United States Dolla <p>The 'currency calculator' below gives you an indication of the cost of purchas <p>February 5, 2017</p><div class="clear-both"></div> <!-- removed clearboth- <p><strong>1 EUR = 1.079992 USD</strong></p> <div class="clear-both"></di <table width="290" border="0" cellspacing="0" cellpadding="3"> <a href="/content/VISA/US/en_us/home/support/consumer/travel-support/exchange e-calculator.html"> <button class="btn btn-default btn-xs"><span class="retur <p><p>This converter uses a single rate per day with respect to any two currencies. Rates displayed may not precisely reflect actual rate applied to transaction amount due to rounding differences, Rates apply to the date the transaction was processed by Visa; this may differ from the actual date of the transaction. Banks may or may not assess foreign transaction fees on cross-border transactions. Fees are applied at banks’ discretion. Please contact your bank for more information.</p>

Eu preciso extrair 1.079992

Estou usando:

sed -E 's:.*(1\.[0-9\.]+).*::g

... o que funciona ... mas existe uma maneira mais elegante?

Como alternativa, existe uma maneira de obter esse valor diretamente de curl ?

(Meu comando completo é: curl 'https://usa.visa.com/support/consumer/travel-support/exchange-rate-calculator.html/?fromCurr=USD&toCurr=EUR&fee=0&exchangedate=02/05/2017' | grep '<p><strong>1' | sed -E 's:.*(1\.[0-9\.]+).*::g' )

    
por Ze'ev 03.03.2017 / 12:36

5 respostas

0

Usando curl para buscar, lynx para análise e awk para extrair

Por favor, não analise XML / HTML com sed , grep , etc. O HTML é livre de contexto, mas sed e amigos são apenas regulares. 1

url='https://usa.visa.com/support/consumer/travel-support/exchange-rate-calculator.html/?fromCurr=USD&toCurr=EUR&fee=0&exchangedate=02/05/2017'
user_agent= 'Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0'

curl -sA "${user_agent}" "${url}"  \
| lynx -stdin -dump                \
| awk '/1 EUR/{ print $4 }'

Você precisa de algum tipo de analisador de HTML para extrair conteúdo com segurança. Aqui, eu uso o lynx (um navegador da Web baseado em texto), mas existem alternativas mais leves.

Aqui, curl recupera a página, então lynx analisa e copia uma representação textual . O /1 EUR/ faz com que awk procure pela string 1 EUR , encontrando apenas a linha:

   1 EUR = 1.079992 USD

Então, { print $4 } faz com que imprima a quarta coluna, 1.079992 .

Solução alternativa sem curl

Como meu analisador de HTML escolhido é lynx , curl não é necessário:

url='https://usa.visa.com/support/consumer/travel-support/exchange-rate-calculator.html/?fromCurr=USD&toCurr=EUR&fee=0&exchangedate=02/05/2017'
user_agent= 'Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0'

lynx -useragent="${user_agent}" -dump "${url}"  \
| awk '/1 EUR/{ print $4 }'

1 Um pcre ( grep -P em algumas implementações) pode descrever alguns conjuntos de strings livres de contexto ou mesmo sensíveis ao contexto, mas nem todos eles. / p>

Editado 2017-12-23 para adicionar uma string user-agent (fingindo ser o Firefox), pois o site atualmente bloqueia curl e lynx .

    
por 07.03.2017 / 01:41
1

Outra solução: html2text

curl -s 'https://usa.visa.com/support/consumer/travel-support/exchange-rate-calculator.html/?fromCurr=USD&toCurr=EUR&fee=0&exchangedate=2/12/2017' \
| html2text \
| grep '1 Euro' \
| awk '{ print $4 }'
    
por 07.03.2017 / 11:31
0

Canalize a saída de curl para o seguinte comando grep :

grep --color -Po '(?<=<strong>1 EUR = )\d+\.\d+(?= USD</strong>)'
    
por 03.03.2017 / 12:56
0
Sugestão: use ferramentas reconhecidas xml / html:

xmllint

curl "$url" | xmllint -html -xpath '//span/strong[2]/text()' - 

xidel

curl "$url" | xidel -s -e "//span/strong[2]" -

ou até mesmo

xidel -e "/span/strong[2]" $url
    
por 07.03.2017 / 13:07
0

Eu usaria pandoc para converter em json e, em seguida, python para extrair os dados. Será muito mais robusto que grep .

Assim, é preciso inserir via stdin:

pandoc  -f html -t json | python3 -c '
import json
import sys

output=[]
data = json.load(sys.stdin)

for i in data[1][0]["c"]:
    if i["t"]=="Strong":
        output.append((i["c"]))

print(output[2][0]["c"])
'
    
por 24.12.2017 / 00:29