web-dev-qa-db-fra.com

obtenir du texte entre guillemets simples à partir d'un fichier html

J'ai un fichier source HTML dont j'ai besoin pour extraire les liens qui s'y trouvent, le nombre de liens varie d'un fichier à l'autre et les liens sont formatés comme tels et entre guillemets simples:

../xxx/yyy/ccc/bbbb/nameoffile.extension

Je dois obtenir le texte entre guillemets simples, remplacer le .. par http:// et exporter le résultat dans un fichier.

Je suis un débutant et cherche une solution pour automatiser ce processus en terminal.

ses fichiers sources HTML et ses liens sont omniprésents dans le fichier. Je dois donc les obtenir un lien par ligne dans un fichier à transférer à mon fichier xargs curl existant.

exemple de fichier serait presque comme ça:

<head>
<body>
<html>

blabla
</>
blibli afg fgfdg sdfg <b> blo blo href= '../xxx/yyy/ccc/bbbb/nameoffile1.extension' target blibli bloblo href= '../xxx/yyy/ccc/bbbb/nameoffile2.extension'  blibli

bloblo href= '../xxx/yyy/ccc/bbbb/nameoffile3.extension'

…

le résultat recherché est un fichier contenant:

http://z.z.com/xxx/yyy/ccc/bbbb/nameoffile1.extension
http://z.z.com/xxx/yyy/ccc/bbbb/nameoffile2.extension
http://z.z.com/xxx/yyy/ccc/bbbb/nameoffile3.extension

quelqu'un peut-il avoir la gentillesse de m'aider à trouver une solution, s'il vous plaît.

fichier source aussi proche que possible:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML>
    <HEAD>
    <TITLE>Inter num num - nil</TITLE>
    <link rel="stylesheet" type="text/css" href="style.css" />
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </HEAD>
    <BODY><table width=1200 align=center class=tabForm><tr><td align=left width=largeur_2 valign=top><img src=Img/logo.gif><br /></td><td align=center valign=center width=largeur_6><h1><font color='#CB150A'>Test d'épreuve</font></h1></td><td align=right valign=top width=largeur_2 class=dataLabel>Reçu le 11/03/2018 à 17:49<br /></td></tr>
    <tr><td width=1200 colspan=3 align=center><b><font color='#CB150A' size=+1>Client : zzz - Référence : 232323  - Désignation : Fiche d'accueil </font></b></color></td></tr>

    </table><BR/><table width=1200 align=center class=tabForm><tr><td class=dataLabelBig width=1200>M numnum ,<BR/><BR/>
    Job citée ci-dessus.<BR/>
    ci-joints toutes les informations nécessaires.
    <BR/><BR/>
    Sandy Jan<BR/>
    [email protected]</font></td></tr></table><br /><table width=1200 align=center class=tabForm><tr><td colspan=2  width=1200 class=dataLabel>Documents nécessaires à votre réponse</td></tr><tr><td colspan=2 width=1200 class=dataLabel><u><b>Job :</b></u> Suivi Travaux - <u><b>Article :</b></u> 232323  - Fiche d'accueil</td></tr><tr><td colspan=2 width=1200 class=dataLabel><a href='../path/path/path/path/path.html' target=_blank><img src=Img/pdf.png border=0> Fiche.html</a></td></tr><tr><td colspan=2 width=1200 class=dataLabel><a href='../path/path/path/path/pathd%27accueil%20traitant-20160621163240.pdf' target=_blank><img src=Img/pdf.png border=0> text.pdf</a></td></tr><tr><td colspan=2 width=1200 class=dataLabel><a href='../path/path/path/path/pathla%20S%E9curit%E9%20%281%29.doc' target=_blank><img src=Img/pdf.png border=0> Fiched'accueil.doc</a></td></tr></table><br /><table width=1200 align=center class=tabForm><tr><td colspan=2 class=dataLabelRed width=1200 >Notre commentaire</td></tr></tr><td colspan=2 class=dataLabel>mise a jour - Attention<br />
Impression <br /><br /></td></tr></table><br /><table width=1200 align=center class=tabForm><form method=post name=formvolume action=?&dossier=111734&coo=135&auth=b182f10b82ba&key=2e7c69213b28d7de6655&action=submit&type=volume enctype=multipart/form-data ><tr><td width=1200 align=left colspan=2 class=dataLabel><h3><img src=Img/h3Arrow.gif border=0>&nbsp;Remise de job  :</h3><br /></td></tr><tr><td align=left valign=top width=120 class=dataLabelRed>Votre commentaire</td><td width=1080 align=left class=dataLabel><textarea cols=200 rows=5 name=comment ></textarea></td></tr><tr><td align=left width=120 class=dataLabelRed>Votre fichier</td><td width=1080 align=left><input type=file name=fichier size=82></td></tr><tr><td align=center colspan=2 width=1200><br /><input type=button class=button value="&nbsp;&nbsp;Remettre votre réponse&nbsp;&nbsp;"  onClick="javascript: var ok=confirm('Etes vous certain de vouloir effectuer cette action ?');if(ok==true){ document.formvolume.submit();}else {return false}" ></form></td></tr><table></table></br><table width=1200 align=center class=tabForm><form method=post name=formvolume_complement action=?&dossier=111734&coo=135&auth=b182f10b82ba&key=2e7c69213b28d7de6655&action=submit_complement&type=volume enctype=multipart/form-data ><tr><td width=1200 align=left colspan=2 class=dataLabel><h3><img src=Img/h3Arrow.gif border=0>&nbsp;Demande de complément, votre réponse  :</h3><br /></td></tr><tr><tr><td align=left valign=top width=120 class=dataLabelRed>Votre commentaire</td><td width=1080 align=left class=dataLabel><textarea cols=200 rows=5 name=comment ></textarea></td></tr><td align=left width=120 class=dataLabelRed>Votre fichier</td><td width=1080 align=left><input type=file name=fichier size=82></td></tr><tr><td align=center colspan=2 width=1200><br /><input type=button class=button value="&nbsp;  Remettre votre réponse &nbsp;"  onClick="javascript: var ok =confirm('Etes v ?');if(ok==true){ document.formvolume_complement.submit();}else {return false}" ></form></td></tr><table></table></BODY></HTML></BODY>
</HTML>
2
grimdex

Des utilitaires tels que sed, awk etc. ne sont pas conçus pour l'analyse de données structurées telles que HTML. Par conséquent, une solution beaucoup plus viable consisterait à utiliser python pour faire de même.

Tout d'abord, assurez-vous que BeautifulSoup est installé par:

Sudo apt-get install python3 python3-bs4

Créez maintenant un nouveau fichier (par exemple test.py) et collez le court script que j'ai écrit à cet effet:

#!/usr/bin/env python3
import sys
from bs4 import BeautifulSoup

DOMAIN = 'z.z.com/'

if  len(sys.argv)<2 or not sys.argv[1].endswith('.html'):
    print("Argument not provided or not .html file", file=sys.stderr)
    exit()

with open(sys.argv[1], 'r', encoding='latin-1') as f:
    webpage = f.read()

soup = BeautifulSoup(webpage, "lxml")
for a in soup.findAll('a', href=True):
    print(a['href'].replace("../","http://"+DOMAIN))

Version Python 2 sur demande:

#!/usr/bin/env python2
import sys
from bs4 import BeautifulSoup

DOMAIN = 'z.z.com/'

if  len(sys.argv)<2 or not sys.argv[1].endswith('.html'):
    print >> sys.stderr, "Argument not provided or not .html file"
    exit()

with open(sys.argv[1], 'rb') as f:
    webpage = f.read().decode("latin-1")

soup = BeautifulSoup(webpage, "html.parser")
for a in soup.findAll('a', href=True):
    print(a['href'].replace("../","http://"+DOMAIN))

Modifiez la variable DOMAIN pour qu'elle corresponde à votre domaine actuel, enregistrez ce script dans le répertoire actuel et exécutez-le comme suit:

./test.py yourfile.html > outputfile

Pour référence, ceci est la sortie produite par le script lors de son exécution avec l'exemple fourni dans la question:

http://z.z.com/path/path/path/path/path.html
http://z.z.com/path/path/path/path/pathd%27accueil%20traitant-20160621163240.pdf
http://z.z.com/path/path/path/path/pathla%20S%E9curit%E9%20%281%29.doc
4
Amith KK

Une autre solution Perl qui utilise un analyseur HTML approprié est la suivante (par exemple _get-links.pl_):

_#!/usr/bin/env Perl

use strict;
use warnings;
use File::Spec;
use WWW::Mechanize;

my $filename = shift or die "Must supply a *.html file\n";
my $absolute_filename = File::Spec->rel2abs($filename);

my $mech = WWW::Mechanize->new();
$mech->get( "file://$absolute_filename" );
my @links = $mech->links();
foreach my $link ( @links ) {
    my $new_link = $link->url;

    if ( $new_link =~ s(^\.\./)(http://z.z.com/) ) {
        print "$new_link\n";
    }
}
_

Vous devrez peut-être installer le module WWW::Mechanize d’abord car ce n’est pas un module de base (ce qui signifie qu’il n’est pas t installé par défaut avec Perl). Pour ce faire, lancez

_Sudo apt install libwww-mechanize-Perl
_

Le script lit le fichier donné, convertit le nom de fichier en un chemin absolu (car nous voulons créer un URI correct comme _file:///path/to/source.html_).

Après avoir extrait les liens (my @links = $mech->links();), il examine l'URL de chaque lien. S'il commence par _../_, cette partie est remplacée par _http://z.z.com/_ et imprimée.

Usage:

_./get-links.pl source.html
_

Sortie:

_http://z.z.com/path/path/path/path/path.html
http://z.z.com/path/path/path/path/pathd%27accueil%20traitant-20160621163240.pdf
http://z.z.com/path/path/path/path/pathla%20S%E9curit%E9%20%281%29.doc
_

Comme @ Amith KK déjà dit dans sa réponse : L'analyse HTML (ou XML) est préférable avec un analyseur approprié car des outils tels que sed et leur type risquent d'échouer quand il y a d'autres éléments dans la source qui ressemblent à un lien mais ne le sont pas.

1
PerlDuck

Convertir du HTML en texte

Comme mentionné dans les commentaires, vous devez convertir html au format texte. Pour cela, il existe un one-liner qui devrait couvrir toutes les bases:

sed 's/&nbsp;/ /g; s/&amp;/\&/g; s/&lt;/\</g; s/&gt;/\>/g; s/&quot;/\"/g; s/#&#39;/\'"'"'/g; s/&ldquo;/\"/g; s/&rdquo;/\"/g;'

Si vous convertissez des centaines de milliers de lignes, les commandes intégrées bash sont beaucoup plus rapides:

#-------------------------------------------------------------------------------
LineOut=""      # Make global
HTMLtoText () {
    LineOut=$1  # Parm 1= Input line
    # Replace external command: Line=$(sed 's/&amp;/\&/g; s/&lt;/\</g; 
    # s/&gt;/\>/g; s/&quot;/\"/g; s/&#39;/\'"'"'/g; s/&ldquo;/\"/g; 
    # s/&rdquo;/\"/g;' <<< "$Line") -- With faster builtin commands.
    LineOut="${LineOut//&nbsp;/ }"
    LineOut="${LineOut//&amp;/&}"
    LineOut="${LineOut//&lt;/<}"
    LineOut="${LineOut//&gt;/>}"
    LineOut="${LineOut//&quot;/'"'}"
    LineOut="${LineOut//&#39;/"'"}"
    LineOut="${LineOut//&ldquo;/'"'}" # TODO: ASCII/ISO for opening quote
    LineOut="${LineOut//&rdquo;/'"'}" # TODO: ASCII/ISO for closing quote
} # HTMLtoText ()

Vérifier si le fichier existe

Pour tester si le fichier existe, utilisez un dérivé de cette fonction :

function validate_url(){
  if [[ `wget -S --spider $1  2>&1 | grep 'HTTP/1.1 200 OK'` ]]; then echo "true"; fi
}

Mettre tous ensemble

Un script final doit encore être écrit sur la base d’exemples de données dérivés d’une page Web valide portant des noms de fichier valides.

0
WinEunuuchs2Unix

Pour extraire des données entre guillemets simples du fichier test.html en remplaçant deux points .. dans les URL avec http://, et enregistrer les données extraites dans le fichier newfile.txt do:

cat test.html | sed -ne 's/^.*'\''\([^'\'']*\)'\''.*$/\1/p' | sed -e 's/\.\./http:\//g' > newfile.txt

Ou essayez sans sed:

cat test.html | grep -Eo "'[^'() ]+'" | tr -d \'\" | Perl -pe 's/../http:\//' > newfile.txt

Cela fonctionne pour l'échantillon de fichier ajouté à la question par l'auteur:

cat test.html | grep -Eo "'[^|'() ]+'" | grep -wE "('..)" | tr -d \'\" | Perl -pe 's/../http:\/\/mysite.mydomain.com/' > newfile.txt
0
Bob