como massagear ou formatar html para analisar com xmstarlet?

5

Primeiramente, preciso executar html no estado selvagem usando algo como jsoup ? Não para torná-lo válido em um sentido humano, pode transformá-lo em rabiscos, mas pelo menos para que xmlstarlet possa processar o arquivo?

De preferência, procurando por um CLI que possa ser instalado e usado da seguinte forma:

massage foo.html > bar.xhtml

ou pelo menos alguma coisa nesse sentido.

Caso de uso:

thufir@doge:~/.html$ 
thufir@doge:~/.html$ curl http://int.soccerway.com/  > soccer.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  188k    0  188k    0     0   313k      0 --:--:-- --:--:-- --:--:--  313k
thufir@doge:~/.html$ 
thufir@doge:~/.html$ xmlstarlet sel -t -v "/html/body/table/tr/td[1]" -n soccer.html 
soccer.html:70.13: xmlParseEntityRef: no name
if (this.$ && this.$.fn && this.$.fn.jquery) {
            ^
soccer.html:70.14: xmlParseEntityRef: no name
if (this.$ && this.$.fn && this.$.fn.jquery) {
             ^
soccer.html:70.26: xmlParseEntityRef: no name
if (this.$ && this.$.fn && this.$.fn.jquery) {
                         ^
soccer.html:70.27: xmlParseEntityRef: no name
if (this.$ && this.$.fn && this.$.fn.jquery) {
                          ^
soccer.html:198.8: Opening and ending tag mismatch: link line 27 and head
</head>
       ^
soccer.html:209.45: EntityRef: expecting ';'
  j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
                                            ^
soccer.html:223.40: xmlParseEntityRef: no name
      if (typeof(e.data) === 'string' && (e.data.indexOf('onEplayerVideoStarted'
                                       ^

O ideal seria executar htmlstarlet diretamente contra a URL, mas parece não haver tal provisão.

Existe uma opção fo para formato , mas não consegui obter resultados diferentes dos apresentados acima.

    
por Thufir 30.07.2017 / 21:18

1 resposta

2

Se você quer apenas as células de dados da tabela, é possível usar xmlstarlet fo seguido por xmlstarlet sel . O principal problema que você está tendo é com o xpath. Se você adicionar alguns elementos "wildcard" ( // ), você obterá o resultado desejado:

# fetch url and send to standard out (-s)
curl -sL http://int.soccerway.com/                          |

# interpret input as html (-H) and try to recover as much as possible (-R)
xmlstarlet fo  -H -R                           2> /dev/null |

# use the following xpath expression and return the value (-t -v), 
# also add a newline after the result (-n)
xmlstarlet sel -t -v '//table//tr//h3/span' -n 2> /dev/null |

# only show the first 10 values
head -n10

Saída:

World - Friendlies
Argentina - Prim B Nacional
Australia - National Premier Leagues
Australia - NPL Youth League
Bangladesh - Premier League
Belarus - Premier League
Benin - Championnat National
Brazil - Serie A
Brazil - Serie D
Brazil - Copa Paulista
    
por 31.07.2017 / 16:44