从大文本/HTML文件中提取URL

5

我有很多文本需要处理以获取有效的URL。

输入的文本类似于HTML,但不是真正的有效HTML。

我一直在尝试使用正则表达式,但遇到了问题。

在你说(或者可能是尖叫 - 我已经阅读了其他关于HTML +正则表达式的问题)“使用解析器”之前,有一件事情你需要考虑:
我正在处理的文件大约有5 GB大小

我不知道任何可以处理这么大的文件而不失败或花费几天时间的解析器。此外,虽然文本内容在很大程度上是HTML,但并不一定是有效的HTML,这意味着它需要一个非常宽容的解析器。最后,不是所有的链接都必须放在标签中(有些可能只是纯文本)。

鉴于我并不真正关心文档结构,有没有更好的选择提取链接?

现在我正在使用以下正则表达式:
\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))) (在grep -E中)
但即使是这样,我也在让它运行了大约3个小时后放弃了。

正则表达式引擎的性能有显著差异吗?我正在使用MacOS的命令行grep。如果有其他兼容实现具有更好的性能,则可能是一个选项。


我不太关心语言/平台,但MacOS /命令行会很好。


它是否应该捕获没有方案的内容?(即没有 http:// - icktoofay
@icktoofay - 那会很好。 - Fake Name
2个回答

2

我最终串联了几个grep命令:

pv -cN source allContent | grep -oP "(?:\"([^\"' ]*?)\")|(?:'([^\"' ]*?)')|(?:([^\"' ]*?) )" | grep -E "(http)|(www)|(\.com)|(\.net)|(\.to)|(\.cc)|(\.info)|(\.org)" | pv -cN out > extrLinks1

我使用pv来给我提供进度指示器。

grep -oP "(?:\"([^\"' ]*?)\")|(?:'([^\"' ]*?)')|(?:([^\"' ]*?) )"
将看起来像单词或带引号的文本提取出来,并且没有空格。

grep -E "(http)|(www)|(\.com)|(\.net)|(\.to)|(\.cc)|(\.info)|(\.org)"
过滤输出,查找任何看起来像URL的内容。

最后,
pv -cN out > extrLinks1
将其输出到文件中,并提供一个漂亮的活动指示器。

我可能会通过sort -u来处理生成的文件,以删除重复条目,但我不想在末尾串联它,因为这会增加另一层复杂性,而且我相信sort会尝试缓冲整个文件,这可能会导致崩溃。


无论如何,现在运行起来看起来需要大约40分钟。我以前不知道pv。它是一个非常酷的实用程序!


0

我觉得你走在正确的道路上,grep应该能够处理一个5Gb的文件。尝试简化你的正则表达式,避免使用|操作符和过多的括号。此外,在对整个文件运行之前,使用head命令获取前100Kb,并使用管道连接多个grep命令以实现更精确的匹配。例如,

head -c 100000 myFile | grep -E "((src)|(href))\b*=\b*[\"'][\w://\.]+[\"']"

这应该非常快,不是吗?


我想要捕获不在<a>标签中的链接。 - Fake Name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接