Ruby 诺科吉里。匹配动态属性名称

Ruby Nokogiri. Match dynamic attribute names

我正在尝试使用 Nokogiri 提取图像 url。 下面的代码有效,但我想以更高效和可扩展的方式进行,而不是无限地执行 elsif。

if doc.at_css("img[itemprop='image']")['src']
    img = doc.at_css("img[itemprop='image']")['src']
elsif doc.at_css("img[itemprop='image']")['data-src']
    img = doc.at_css("img[itemprop='image']")['data-src']
elsif doc.at_css("img[itemprop='image']")['data-react-src']
    img = doc.at_css("img[itemprop='image']")['data-react-src']
...

我想学习这两种方法:

1) 普通 Ruby 方式:像迭代属性名称一样 ['src', 'data-src', 'data-react-src', etc...]

2) Nokogiri 正则表达式或 xpath,方法:

'src' || 'data-src' || 'data-react-src

像这样:

doc.at_css("img[itemprop='image']")['src' || 'data-src' || '数据反应源]

更好的是,将属性名称存储在变量中:

my_attributes = ['src' || 'data-src' || 'data-react-src]

doc.at_css("img[itemprop='image']").[my_attributes]

3) 如果有比以前更有效的方法

试试这个:

attributes = %w[src data-src data-react-src]
elem = doc.at_css("img[itemprop='image']")
attr = attributes.find { |attr| elem[attr] }
doc[attr] if attr

它的作用:

  1. 保存静态和动态属性列表。将来添加更多。列表顺序很重要 [ref #3]
  2. elem 包含元素 (Nokogiri::XML::Element)。我们不想多次获取它来优化。
  3. attr 包含元素 响应 的第一个 属性 。如果找到 src,则不会尝试在 data-src 中查找,依此类推。这样我们优化了迭代。
  4. return 该 attr 处的值(如果属性可用)。

希望对您有所帮助。