0

那么我必须找到一种方法来提取<div id="links"></table>标签之间的所有链接。如果有多个链接,则应在 url 之间添加 '\n' 字符:“$URL1\n$URL2”。

<div id="links">
<table>
<td><a href="URL">url</a></td>
<td><a href="URL">url</a></td>
</table>
<table>
..
</table>
</div>

<div>标签和第一个标签之间的那些</table>。那么除了sed还有其他方法吗?

谢谢你。

4

4 回答 4

2

正如每天在 SO 上发布的那样:您无法使用正则表达式处理 HTML。您能否提供一些示例说明为什么使用正则表达式难以解析 XML 和 HTML?

对于像 sed 这样有限的工具,它的基本正则表达式是双倍的。

如果您的输入类型非常有限,以至于每个链接都采用完全相同的格式,则可能有可能,在这种情况下,您必须发布该格式的示例。但是对于一般的HTML页面,是做不到的。

ETA 给出了您的示例:在最简单的级别上,由于每个 URL 已经在其自己的行上,您可以选择看起来正确的那些并丢弃您不想要的位:

#!/bin/sed -f
s/^<td><a href="\(.*\)">.*<\/a><\/td>$/\1/p
d

但是请注意,这仍会使 URL 保留其 HTML 编码形式。如果生成此文件的脚本正确地对其 URL 进行 HTML 编码,则您必须将 lt/gt/quot/amp 实体引用的任何实例替换回它们的纯字符形式 '<>"&'。实际上您可能会遇到的唯一一个是 &/amp,这在 URL 中确实很常见。

但!这还不是所有可能发生的 HTML 编码。那里可能还有其他 HTML 实体引用,例如 eacute(现在我们有了 IRI,这将是有效的),或数字字符引用(十进制和十六进制)。包括 Unicode 在内的字符有 200 万多种潜在的编码形式……在 sed 中单独替换每个编码形式将是一项繁重的工作。

虽然如果您知道生成器脚本永远不会输出任何这些,您可能会侥幸逃脱,但 HTML 解析器仍然是最好的。(或者,如果您知道它是格式良好的 XHTML,您可以使用更简单的 XML 解析器,它往往内置于现代语言的标准库中。)

于 2009-08-18T11:28:37.343 回答
0

您可以访问 AWK 吗?AWK 和 sed 的组合可能会满足您的需求,前提是:

  • html比较简单
  • html 不会突然改变(我的意思是形式,而不是内容)
  • html 并不过分复杂。

不能用正则表达式处理 HTML 是错误的。确实,在一般情况下,您不能使用正则表达式处理 HTML(或 XML),因为它们允许任意嵌套,而正则表达式不能很好地进行递归 - 或者根本不能进行递归。但是,如果您的 HTML 相对“扁平”,那么您当然可以使用正则表达式做很多事情。

我不能确切地告诉你该怎么做,因为我已经忘记了我在大学里学到的小 AWK 和 sed,但这让我觉得可行:

  • 找到字符串<div id="links">
  • 现在找到字符串<table>
  • 现在找到字符串<td>...</td>并从中获取链接(这是正则表达式部分)。
  • 将其附加到 var$links
  • 直到找到字符串</table>
  • 最后,打印$links用 . 分隔每个链接\n

同样,这只是简单案例的伪代码。但它可能只是工作。

我提到 AWK 是因为,即使您无法访问 Perl,也往往会同时安装 sed 和 AWK。

最后,对于纯 sed 解决方案,您还可以查看此 sed 配方并根据您的需要进行调整。

于 2009-08-18T13:03:42.233 回答
0

如果您可以访问 python,我会推荐 BeautifulSoup。一个很好的用于处理 HTML 的 Python 库。以下代码从给定资源收集链接,该资源是http://www.foo.com等网页的全名,并将它们存储在文件中。希望这可以帮助。

import sys, os
from urllib import urlopen
from BeautifulSoup import BeautifulSoup

fileLinksName = "links.dat"

if __name__ == "__main__":
    try:
        # get all links so far
        fileLinks = open(fileLinksName)

        links = fileLinks.read().split('\n')

        fileLinks.close()

        htmlFileSoup = BeautifulSoup(urlopen(sys.argv[1]).read())

        anchorList = htmlFileSoup.findAll('a')

        for htmlAnchor in anchorList:
            print htmlAnchor
            if 'href' in htmlAnchor:
                links.append(htmlAnchor)

        for link in links:
            print link
    except:
        print sys.exc_info()
        exit()
于 2009-08-18T12:07:04.473 回答
0

如果您不尝试查看标签,而只是查找 URL,这可能是可能的。

如果这些是页面中唯一的 URL,您可以编写一个模式来查找引号之间的 URL,例如:

"[a-z]+://[^"]+" 
于 2009-08-18T12:13:12.780 回答