我正在尝试使用grep和cut从HTML文件中提取URL。链接如下所示:
<a href="http://examplewebsite.com/">
其他网站都有.net
,.gov
但我认为我可以在截止点之前提出>
。所以我知道我可以使用grep并以某种方式剪切掉http和.com之前的所有内容,但是我已经坚持了一段时间。
<>
强制将其视为HTML标记。
我正在尝试使用grep和cut从HTML文件中提取URL。链接如下所示:
<a href="http://examplewebsite.com/">
其他网站都有.net
,.gov
但我认为我可以在截止点之前提出>
。所以我知道我可以使用grep并以某种方式剪切掉http和.com之前的所有内容,但是我已经坚持了一段时间。
<>
强制将其视为HTML标记。
Answers:
正如我在评论中说的那样,用正则表达式解析HTML通常不是一个好主意,但是如果您解析的HTML表现良好,有时您可以摆脱它。
为了只获取元素href
属性中的URL <a>
,我发现在多个阶段中最容易做到这一点。从您的评论看来,您只需要顶级域名,而不是完整URL。在这种情况下,您可以使用以下方式:
grep -Eoi '<a [^>]+>' source.html |
grep -Eo 'href="[^\"]+"' |
grep -Eo '(http|https)://[^/"]+'
source.html
包含要解析的HTML代码的文件在哪里。
此代码将打印所有出现在每一行href
中任何<a>
元素属性的顶级URL 。第-i
一个grep
命令的选项是确保它可以同时在<a>
和<A>
元素上使用。我想您也-i
可以使用第二种方法grep
来捕获大写HREF
属性OTOH,我更喜欢忽略这种损坏的HTML。:)
处理内容 http://google.com/
wget -qO- http://google.com/ |
grep -Eoi '<a [^>]+>' |
grep -Eo 'href="[^\"]+"' |
grep -Eo '(http|https)://[^/"]+'
输出
http://www.google.com.au
http://maps.google.com.au
https://play.google.com
http://www.youtube.com
http://news.google.com.au
https://mail.google.com
https://drive.google.com
http://www.google.com.au
http://www.google.com.au
https://accounts.google.com
http://www.google.com.au
https://www.google.com
https://plus.google.com
http://www.google.com.au
当我重定向到澳大利亚Google页面时,我的输出与其他示例略有不同。
://
我们只接受第一个/
或之前的字符"
。但是,如果您想查看完整的URL,请将命令更改为grep -Eo '(http|https)://[^"]+
。该行的另一个选项是grep -Eo '(http|https)://[^?"]+'
切断查询选项。但是,该变体仍将打印包含在另一个URL中的URL作为查询参数,但是它们将被打印在单独的行上。
不知道您是否受限于工具:
但是正则表达式可能不是最好的方式,但是下面是我整理的一个示例:
cat urls.html | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u
输出:
bob@bob-NE722:~s$ wget -qO- https://stackoverflow.com/ | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u
https://stackauth.com
https://meta.stackoverflow.com
https://cdn.sstatic.net/Img/svg-icons
https://stackoverflow.com
https://www.stackoverflowbusiness.com/talent
https://www.stackoverflowbusiness.com/advertising
https://stackoverflow.com/users/login?ssrc=head
https://stackoverflow.com/users/signup?ssrc=head
https://stackoverflow.com
https://stackoverflow.com/help
https://chat.stackoverflow.com
https://meta.stackoverflow.com
...
您也可以添加\d
以捕获其他数字类型。
sort -u
?
如果您的grep支持Perl正则表达式:
grep -Po '(?<=href=")[^"]*(?=")'
(?<=href=")
并且(?=")
是环视的表达式href
属性。这需要-P
选项。-o
打印匹配的文本。例如:
$ curl -sL https://www.google.com | grep -Po '(?<=href=")[^"]*(?=")'
/search?
https://www.google.co.in/imghp?hl=en&tab=wi
https://maps.google.co.in/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
https://www.youtube.com/?gl=IN&tab=w1
https://news.google.co.in/nwshp?hl=en&tab=wn
...
与往常一样,不能保证这些是有效的URI,也不保证您正在解析的HTML将是有效的。
作为非正则表达式的替代品,请使用pup:
pup 'a[href] attr{href}' < yourfile.html
将查找所有a
具有href
属性的元素,然后显示该href
属性的值。
要安装pup
,您需要Go(一种编程语言):
sudo apt-get install golang
sudo go get github.com/ericchiang/pup
该解决方案的优点是它不依赖于正确格式化的HTML。
pup
,需要时间安装....
pup 'a.classname[href] attr{href}' < tut.html >links.md
我在这里找到了一个解决方案,恕我直言,它比这里提出的解决方案简单得多,而且可能更快。我做了一些调整以支持https文件。但是TD; TR版本是...
PS:您可以将站点URL替换为文件路径,并且将以相同的方式工作。
lynx -dump -listonly -nonumbers "http://www.goggle.com" > links.txt
lynx -dump -listonly -nonumbers "some-file.html" > links.txt
如果您只想查看链接而不是将链接放在文件中,请尝试使用此链接...
lynx -dump -listonly -nonumbers "http://www.google.com"
lynx -dump -listonly -nonumbers "some-file.html"
结果将类似于以下内容...
http://www.google.ca/imghp?hl=en&tab=wi
http://maps.google.ca/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
http://www.youtube.com/?gl=CA&tab=w1
http://news.google.ca/nwshp?hl=en&tab=wn
https://mail.google.com/mail/?tab=wm
https://drive.google.com/?tab=wo
https://www.google.ca/intl/en/options/
http://www.google.ca/history/optout?hl=en
...
etc.
对于我的用例,这很好。但是请注意,如今人们为库的CDN URI添加了诸如src =“ // blah.tld”之类的链接。我不想在检索的链接中看到这些内容。
无需尝试检查href或其他来源的链接,因为默认情况下,“ lynx -dump”将提取给定页面中的所有可点击链接。因此,在此之后,您唯一需要做的就是使用grep解析“ lynx -dump”的结果,以获得相同结果的更原始版本。
wget -qO- google.com |
tr \" \\n | grep https\*://
...可能会做得很好。如所写,它打印:
http://schema.org/WebPage
http://www.google.com/imghp?hl=en&tab=wi
http://maps.google.com/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
http://www.youtube.com/?tab=w1
http://news.google.com/nwshp?hl=en&tab=wn
https://mail.google.com/mail/?tab=wm
https://drive.google.com/?tab=wo
http://www.google.com/intl/en/options/
http://www.google.com/history/optout?hl=en
https://accounts.google.com/ServiceLogin?hl=en&continue=http://www.google.com/
https://www.google.com/culturalinstitute/project/the-holocaust?utm_source=google&utm_medium=hppromo&utm_campaign=auschwitz_q1&utm_content=desktop
https://plus.google.com/116899029375914044550
如果仅匹配链接以及这些顶级域中的链接很重要,则可以执行以下操作:
wget -qO- google.com |
sed '/\n/P;//!s|<a[^>]*\(https*://[^/"]*\)|\n\1\n|;D'
...或类似的东西-尽管对于某些sed
s,您可能需要用字面的\n
斜线字符代替最后两个n
s。
按照上面的命令,上面的命令显示:
http://www.google.com
http://maps.google.com
https://play.google.com
http://www.youtube.com
http://news.google.com
https://mail.google.com
https://drive.google.com
http://www.google.com
http://www.google.com
http://www.google.com
https://www.google.com
https://plus.google.com
...并且对于任何一种情况(但对于后一种情况,可能都是最有用的),您可以将|sort -u
过滤器添加到末尾以获取列表sort
ed并删除重复项。
echo "<a href="http://examplewebsite.com/">"|sed -r 's:<.*"::g'|sed 's:/">$::g'