从html文件的单引号中获取文本

我有一个html源文件,我需要提取其中的链接,链接数量因文件而异,链接格式如此,并且在单引号内:

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

我需要在单引号之间获取文本,用http://替换..并将结果输出到文件。

我是一个新手,正在寻找一个解决方案来自动化终端中的这个过程。

它的html源文件和链接在文件中无处不在,我需要在文件中输出每行一个链接传递给我现有的xargs curl进行下载。

样本文件几乎是这样的:

    blabla  blibli afg fgfdg sdfg  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' … 

查找的结果是包含以下内容的文件:

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

请有人帮助我找到解决方案。

源文件尽可能接近:

   Inter num num - nil    

Test d'épreuve

Reçu le 11/03/2018 à 17:49
Client : zzz - Référence : 232323 - Désignation : Fiche d'accueil

M numnum ,

Job citée ci-dessus.
ci-joints toutes les informations nécessaires.

Sandy Jan
test@test.com

Documents nécessaires à votre réponse
Job : Suivi Travaux - Article : 232323 - Fiche d'accueil
Fiche.html
text.pdf
Fiched'accueil.doc

Notre commentaire
mise a jour - Attention
Impression


 Remise de job :


Votre commentaire
Votre fichier


 Demande de complément, votre réponse :


Votre commentaire
Votre fichier

诸如sedawk等实用程序不是用于解析诸如html的结构化数据。 因此,一个更可行的解决方案是使用python来做同样的事情。

首先,确保通过以下方式安装BeautifulSoup

 sudo apt-get install python3 python3-bs4 

现在创建一个新文件(例如test.py )并粘贴我为此目的编写的短脚本:

 #!/usr/bin/env python3 import sys from bs4 import BeautifulSoup DOMAIN = 'zzcom/' 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)) 

根据要求提供Python 2版本:

 #!/usr/bin/env python2 import sys from bs4 import BeautifulSoup DOMAIN = 'zzcom/' 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)) 

修改DOMAIN变量以匹配您的实际域,将此脚本保存在当前目录中并按如下方式运行:

 ./test.py yourfile.html > outputfile 

作为参考,这是脚本在运行它时产生的输出,问题中提供了示例:

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

另一个使用正确的HTML解析器的Perl解决方案如下(比如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://zzcom/) ) { print "$new_link\n"; } } 

您可能需要首先安装WWW::Mechanize模块,因为它不是核心模块 (意味着默认情况下它不与Perl一起安装)。 为此,请运行

 sudo apt install libwww-mechanize-perl 

该脚本读取给定文件,将文件名转换为绝对路径(因为我们要构建一个正确的URI,如file:///path/to/source.html )。

解压缩链接后( my @links = $mech->links(); )它检查每个链接的URL,如果它以../开头,那么该部分将被http://zzcom/替换并打印出来。

用法:

 ./get-links.pl source.html 

输出:

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

正如@Amith KK在他的回答中所说:解析HTML(或XML)最好用一个合适的解析器来完成,因为当源中的其他元素看起来像链接但是没有时,像sed这样的工具可能会失败。

要在文件test.html单引号之间提取数据,并在带有http:// URL中替换两个点..并将提取的数据保存到文件newfile.txt请执行以下操作:

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

或者尝试没有sed:

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

这适用于作者提问的文件样本:

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

将HTML转换为文本

如评论中所述,您需要将html转换为文本格式。 为此,有一个单线应覆盖所有基地:

 sed 's/ / /g; s/&/\&/g; s/</\/g; s/"/\"/g; s/#'/\'"'"'/g; s/“/\"/g; s/”/\"/g;' 

如果你要转换成千上万行中的100行,那么bash内置命令要快很多倍:

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

检查文件是否存在

要测试文件是否存在,请使用此函数的派生:

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

把它们放在一起

仍然需要根据从具有有效文件名的有效网页派生的样本数据来编写最终脚本。