我想从google.com中提取链接;我的HTML代码如下所示:
<a href="http://www.test.com/" class="l"
我花了大约五分钟找到一个使用www.rubular.com工作的正则表达式。 它是:
"(.*?)" class="l"
代码是:
require "open-uri"
url = "http://www.google.com/search?q=ruby"
source = open(url).read()
links = source.scan(/"(.*?)" class="l"/)
links.each { |link| puts #{link}
}
问题是,是不是输出了网站链接。
答案 0 :(得分:4)
这些链接实际上有class=l
而不是class="l"
。顺便说一下,为了计算这个问题,我在方法中添加了一些日志记录,以便您可以在各个阶段查看输出并进行调试。我搜索了你期望找到的字符串但没找到它,这就是你的正则表达式失败的原因。所以我找了你想要的正确字符串并相应地更改了正则表达式。调试技巧很方便。
require "open-uri"
url = "http://www.google.com/search?q=ruby"
source = open(url).read
puts "--- PAGE SOURCE ---"
puts source
links = source.scan(/<a.+?href="(.+?)".+?class=l/)
puts "--- FOUND THIS MANY LINKS ---"
puts links.size
puts "--- PRINTING LINKS ---"
links.each do |link|
puts "- #{link}"
end
我也改进了你的正则表达式。您正在寻找一些以打开标记(<a
)开头的文本,然后是您不关心的某些字符(.+?
),一个href属性({{1} }),要捕获的href属性的内容(href="
),一些空格或其他属性((.+?)
),最后是类attrubute(.+?
)。
我在那里有三个地方class=l
。 .+?
表示任何字符,.
表示必须有一个或多个字符,而+
表示?
应该尝试匹配尽可能短的字符串。
答案 1 :(得分:2)
说穿了,问题是你正在使用正则表达式。问题是HTML就是所谓的context-free language,而正则表达式只能是regular languages所谓的语言类。
您应该做的是将页面数据发送到可以处理HTML代码的解析器,例如Hpricot,然后遍历从解析器获得的解析树。
答案 2 :(得分:0)
我出了什么问题?
您正在尝试使用正则表达式解析HTML。不要那样做。正则表达式无法覆盖即使是有效的XHTML所允许的语法范围,更不用说现实世界的标签汤了。使用HTML解析器库,例如Hpricot。
FWIW,当我获取“http://www.google.com/search?q=ruby”时,我在返回的标记中的任何地方都没有收到“class =”l“'。也许这取决于您使用的是哪个本地Google和/或您是否已登录或拥有Google Cookie。 (你的脚本和我一样,不会。)