有没有办法解析在 ruby 的标签中包含 javascript 的 html?
Is there a way to parse html that include javascript in tags in ruby?
我正在 Ruby 解决网络抓取问题。我已经看到多个与此相关的问题和答案,但在 none 中我看到 HTML 其中包含一些 JavaScript 框架,但我不知道如何去做。我只想 select HTML 和 return 对象数组。以下是我的脚本和 HTML 代码。 name、currency、balance等值的HTML类都差不多,请问如何实现?
content = document.css("div.acc-list").map do |parameters|
name = parameters.at_css("p.s3.bold.row.acDesc").text.strip, # argument?
currency = parameters.at_css(".row.ccy").text.strip, # argument?
balance = parameters.at_css(".row.acyOpeningBal").text.strip # argument?
Account.new name, currency, balance
end
pp content
这些 HTML 段落位于其他多个 类 中,我认为这是框架的原因。但是,它们在 <div class = acc-list div>...</div>
中,我认为当我将 "div.acc-list" 分配给 "content" 变量时我做对了。
<!-- HTML for name -->
<td bindonce="" ng-repeat="col in gridOptions.columns" sg-bind-html-compile="col.cellTemplate" bo-class="col.className" bo-style="{width: col.remWidth }"
class="ng-scope icon-two-line-col" style="width: 17.3333rem;">
<div style="width: 17.333333333333332rem" class="first-cell cellText ng-scope">
<i bo-class="{'active':row.selected }" class="i-32 active icon i-circle-account"></i>
<div class="info-wrapper" style="">
<p class="s3 bold" bo-bind="row.acDesc">Name_value</p> # value
<a ui-sref="app.layout.ACCOUNTS.DETAILS.{ID}({id:'091601003439274'})" href="/Bank/accounts/details/BG37FINV91503006938102">
<span bo-bind="row.iban">BG37FINV91503006938102</span>
<i class="i-arrow-right-5x8"></i>
</a>
</div>
</div>
</td>
<!-- HTML for currency -->
<td bindonce="" ng-repeat="col in gridOptions.columns" sg-bind-html-compile="col.cellTemplate" bo-class="col.className" bo-style="{width: col.remWidth }"
class="ng-scope" style="width: 4.4rem;">
<div style="width: 4.4rem" class="text-center cellText ng-scope">
<span bo-bind="row.ccy">EUR</span> # value
</div>
</td>
<!-- HTML for balance -->
<td bindonce="" ng-repeat="col in gridOptions.columns" sg-bind-html-compile="col.cellTemplate" bo-class="col.className" bo-style="{width: col.remWidth }"
class="ng-scope" style="width: 8.73333rem;">
<div style="width: 8.733333333333333rem" class="text-right cellText ng-scope">
<span bo-bind="row.acyAvlBal | sgCurrency">1 523.08</span> # value
</div>
</td>
使用CSS:
require 'nokogiri'
document = Nokogiri::HTML(<<EOT)
<div class="acc-list">
<!-- HTML for name -->
<td>
<div class="first-cell cellText ng-scope">
<div class="info-wrapper">
<!-- # value -->
<p class="s3 bold">Name_value</p>
</div>
</div>
</td>
<!-- HTML for currency -->
<td>
<div class="text-center cellText ng-scope">
<!-- # value -->
<span>EUR</span>
</div>
</td>
<!-- HTML for balance -->
<td>
<div class="text-right cellText ng-scope">
<!-- # value -->
<span>1 523.08</span>
</div>
</td>
</div>
EOT
现在 DOM 已加载:
content = document.css('div.acc-list').map do |div|
name = div.at("p.s3.bold").text.strip # => "Name_value"
currency = div.at("div.text-center > span").text.strip # => "EUR"
balance = div.at("div.text-right > span").text.strip # => "1 523.08"
[ name, currency, balance ]
end
# => [["Name_value", "EUR", "1 523.08"]]
您的 HTML 示例包含大量无关信息,这些信息掩盖了该特定森林中的树木。我把它去掉了,因为它没有用。 (而且,在提交问题时,您应该自动将其作为简化非必要信息的一部分,以便我们都可以专注于实际问题。)
CSS不关心节点名称以外的参数,class
和id
。如果需要细粒度访问,class
可以在 class 的定义中链接参数,但通常可以使用更通用的 class 选择器;这仅取决于 HTML.
大多数 XML 和 HTML 解析基本上是相同的策略:找到一个外部占位符,查看它的内部并迭代获取所需的信息。我无法完全证明这一点,因为您的示例只有外部 div,但您可能可以想象处理内部循环的必要代码。
at_css
几乎等同于 at
,而 Nokogiri 在 99.9% 的情况下足够聪明来确定选择器是 CSS 还是 XPath,所以我倾向于使用 at
因为我手指比较懒
我正在 Ruby 解决网络抓取问题。我已经看到多个与此相关的问题和答案,但在 none 中我看到 HTML 其中包含一些 JavaScript 框架,但我不知道如何去做。我只想 select HTML 和 return 对象数组。以下是我的脚本和 HTML 代码。 name、currency、balance等值的HTML类都差不多,请问如何实现?
content = document.css("div.acc-list").map do |parameters|
name = parameters.at_css("p.s3.bold.row.acDesc").text.strip, # argument?
currency = parameters.at_css(".row.ccy").text.strip, # argument?
balance = parameters.at_css(".row.acyOpeningBal").text.strip # argument?
Account.new name, currency, balance
end
pp content
这些 HTML 段落位于其他多个 类 中,我认为这是框架的原因。但是,它们在 <div class = acc-list div>...</div>
中,我认为当我将 "div.acc-list" 分配给 "content" 变量时我做对了。
<!-- HTML for name -->
<td bindonce="" ng-repeat="col in gridOptions.columns" sg-bind-html-compile="col.cellTemplate" bo-class="col.className" bo-style="{width: col.remWidth }"
class="ng-scope icon-two-line-col" style="width: 17.3333rem;">
<div style="width: 17.333333333333332rem" class="first-cell cellText ng-scope">
<i bo-class="{'active':row.selected }" class="i-32 active icon i-circle-account"></i>
<div class="info-wrapper" style="">
<p class="s3 bold" bo-bind="row.acDesc">Name_value</p> # value
<a ui-sref="app.layout.ACCOUNTS.DETAILS.{ID}({id:'091601003439274'})" href="/Bank/accounts/details/BG37FINV91503006938102">
<span bo-bind="row.iban">BG37FINV91503006938102</span>
<i class="i-arrow-right-5x8"></i>
</a>
</div>
</div>
</td>
<!-- HTML for currency -->
<td bindonce="" ng-repeat="col in gridOptions.columns" sg-bind-html-compile="col.cellTemplate" bo-class="col.className" bo-style="{width: col.remWidth }"
class="ng-scope" style="width: 4.4rem;">
<div style="width: 4.4rem" class="text-center cellText ng-scope">
<span bo-bind="row.ccy">EUR</span> # value
</div>
</td>
<!-- HTML for balance -->
<td bindonce="" ng-repeat="col in gridOptions.columns" sg-bind-html-compile="col.cellTemplate" bo-class="col.className" bo-style="{width: col.remWidth }"
class="ng-scope" style="width: 8.73333rem;">
<div style="width: 8.733333333333333rem" class="text-right cellText ng-scope">
<span bo-bind="row.acyAvlBal | sgCurrency">1 523.08</span> # value
</div>
</td>
使用CSS:
require 'nokogiri'
document = Nokogiri::HTML(<<EOT)
<div class="acc-list">
<!-- HTML for name -->
<td>
<div class="first-cell cellText ng-scope">
<div class="info-wrapper">
<!-- # value -->
<p class="s3 bold">Name_value</p>
</div>
</div>
</td>
<!-- HTML for currency -->
<td>
<div class="text-center cellText ng-scope">
<!-- # value -->
<span>EUR</span>
</div>
</td>
<!-- HTML for balance -->
<td>
<div class="text-right cellText ng-scope">
<!-- # value -->
<span>1 523.08</span>
</div>
</td>
</div>
EOT
现在 DOM 已加载:
content = document.css('div.acc-list').map do |div|
name = div.at("p.s3.bold").text.strip # => "Name_value"
currency = div.at("div.text-center > span").text.strip # => "EUR"
balance = div.at("div.text-right > span").text.strip # => "1 523.08"
[ name, currency, balance ]
end
# => [["Name_value", "EUR", "1 523.08"]]
您的 HTML 示例包含大量无关信息,这些信息掩盖了该特定森林中的树木。我把它去掉了,因为它没有用。 (而且,在提交问题时,您应该自动将其作为简化非必要信息的一部分,以便我们都可以专注于实际问题。)
CSS不关心节点名称以外的参数,class
和id
。如果需要细粒度访问,class
可以在 class 的定义中链接参数,但通常可以使用更通用的 class 选择器;这仅取决于 HTML.
大多数 XML 和 HTML 解析基本上是相同的策略:找到一个外部占位符,查看它的内部并迭代获取所需的信息。我无法完全证明这一点,因为您的示例只有外部 div,但您可能可以想象处理内部循环的必要代码。
at_css
几乎等同于 at
,而 Nokogiri 在 99.9% 的情况下足够聪明来确定选择器是 CSS 还是 XPath,所以我倾向于使用 at
因为我手指比较懒