如何从JavaScript的'onclick window.open'事件中爬取URL?

3

我正在尝试从一个使用JavaScript的页面中爬取URL。该页面没有直接提供链接,而是为许多表格行创建了onClick事件。当您点击行时,它会将您带到链接。

我尝试使用Mechanize来爬取URL:

agent = Mechanize.new
page = agent.get(url)

page.links_with(:href => /^http?/).each do |link|
  puts link.href
end

但是,通过HREF引用查找链接在这里不起作用,因为它们作为onClick事件的一部分出现在页面上:

<tr onclick="window.open('/someurl');">

有没有一种好的方法使用Mechanize或其他gem来解析页面上的代码并提取嵌入在onClick事件中的URL?

如果没有现成的好方案,那么最好的正则表达式是什么?我对正则表达式还不太熟悉,所以还不能自己编写出一个。


1
所有的链接格式都一样吗? - Brad
如果可能的话,还可以添加您正在抓取的页面的URL,这样人们就可以查看源代码。这有助于更快地获得答案。 - Casper
1个回答

4
你应该使用解析器。正则表达式和HTML/XML不太搭配,因为正则表达式并不是设计用来处理HTML和XML文档中包含的不规则性的。一些非常简单的任务可能可以使用模式匹配,但你很快就会发现它们很容易被破坏,尤其是当HTML发生变化时。
Ruby的Mechanize内部使用Nokogiri,这是一个很好的获取参数的方法。你可以访问Mechanize的内部Nokogiri文档,并从中找到<tr>标记。
require 'mechanize'

page = Mechanize.new
page = agent.get('http://somesite.foo.com')

page.search('tr[onclick]').map{ |n| n['onclick'][/\(['"]([^)]+)['"]\)/, 1] }

如果我直接使用Nokogiri解析此片段:
<tr onclick="window.open('/someurl');">

我可以做到这个:
require 'nokogiri'

page = Nokogiri::HTML(%[<tr onclick="window.open('/someurl');">])
page.search('tr[onclick]').map{ |n| n['onclick'][/\(['"]([^)]+)['"]\)/, 1] }
=> ["/someurl"]

请注意,我正在使用CSS选择器'tr[onclick]'进行搜索,这使得查找特定节点变得非常容易。如果您了解JavaScript、CSS或jQuery,您将很容易通过Nokogiri内置的CSS支持来学习它。
另外,
n['onclick'][/\(['"]([^)]+)['"]\)/, 1]

也可以用以下方式书写:

n['onclick'][/\(([^)]+)\)/, 1][1..-2]

太好了 - 搜索和映射完美地工作了。我应该这样解释正则表达式吗:1)查找开括号2)查找单引号或双引号3)查找所有不是闭括号的字符4)查找闭引号5)查找闭括号...?传递的“1”参数代表什么?谢谢! - Cam Norgate
这就是如何读取正则表达式。1 的含义留给你自己去理解。请参阅 String.[] 的文档。 - the Tin Man

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