如何从网页中复制特定元素

时间:2013-10-21 16:22:47

标签: xpath firebug element webpage xmlstarlet

我的目标是从网页获取特定文本区域。想象一下,就像你能够在页面的任何地方绘制一个矩形,这个矩形中的所有内容都将被复制到剪贴板中。我正在使用FireBug(随意提出另一种解决方案,我已经搜索了插件或书签,但没有找到任何有用的东西),它的控制台窗口和XPath用于此目的。我想要获得的值采用以下格式(这是从FireBug“HTML inspect”中观察到的):

<span class="number3_0" title="Numbers">3.00</span>

所以我最终得到了以下代码,我从FireBug控制台发出代码: $x("//span[@title='Numbers']/text()")

在此之后我得到这样的东西:

[<TextNode textContent="2.00">, <TextNode textContent="2.00">, <TextNode textContent="2.00">, <TextNode textContent="2.00">, <TextNode textContent="3.00">]

在此之后,我在[点击(用鼠标右键)并选择Inspect in DOM panel然后按ctrl+a并按以下格式复制/粘贴数据:

0   <TextNode textContent="2.00">
1   <TextNode textContent="2.00">
2   <TextNode textContent="2.00">
3   <TextNode textContent="2.00">
4   <TextNode textContent="3.00">

您可以假设textContent的值是我感兴趣的信息。我试图修改原始XPath查询以仅返回此数字但没有运气。我是:

按照Xpath - get only node content without other elements

的建议将整个查询打包到string()

试图弄清楚这个是如何工作的Extracting text in between nodes through XPath还有很多。

为了能够获得所需的值,我使用了一些bash-scripting + xml-formatting,在这个繁琐/容易出错的任务后,我得到以下格式:

<?xml version="1.0"?>
<head>
  <TextNode textContent="2.00"/>
  <TextNode textContent="2.00"/>
  <TextNode textContent="2.00"/>
  <TextNode textContent="2.00"/>
  <TextNode textContent="3.00"/>
  <TextNode textContent="3.00"/>
</head>

现在我使用xmlstarlet来获取这些值(是的,我知道我可以在前一步中使用regexp并拥有我需要的所有数据。但我对DOM / XPath解析感兴趣并试图弄清楚如何它正在以下列方式工作:

cat input | xmlstarlet sel -t -m "//TextNode" -v 'concat(@textContent," 
")'

这个finnaly给了我想要的输出:

2.00
2.00
2.00
2.00
3.00

我的问题有点泛:

  1. 这个糟糕的漫长过程如何实现自动化?
  2. 如何修改FireBug中使用的原始XPath字符串 $x("//span[@title='Numbers']/text()")只能立即获得 数字并保存自己的其余步骤?
  3. 我仍然不熟悉xmlstarlet,特别是选择 (sel)模式让我发疯。我见过各种各样的组合 以下选项:

    -c或--copy-of-print copy of XPATH expression

    -v或--value-of-print值XPATH表达式

    -o或--output - 输出字符串文字

    -m或--match - 匹配XPATH表达式

  4. 有人可以解释何时使用哪一个?如果可能的话,特别是在例子中看到它会很高兴。如果有兴趣,有各种上述选项的组合,我不太了解: http://www.grahl.ch/blog/minutiae-return-content-element-xmlstarlet Extracting and dumping elements using xmlstarlet Testing for an XML attribute

    4.。)关于xmlstarlet的最后一个问题是一个有点美化的语法糖,如何获得漂亮的换行分离输出,你可以看到我'作弊'添加换行符作为分隔符,但当我尝试它逃避这样的角色:

    cat input | xmlstarlet sel -t -m "//TextNode" -v 'concat(@textContent,"\n")'

    它没有用,也是我从中学到很多用这种“丑陋”方式的原始参考http://www.ibm.com/developerworks/library/x-starlet/index.html

    PS:也许这些步骤可以通过curl + xmlstarlet进行简化,但是对于需要登录或其他东西的页面也可以使用FireBug选项。

    感谢您的所有想法。

2 个答案:

答案 0 :(得分:2)

从我收集到的内容中,您希望从标题为“Numbers”的跨度中收集数字,并希望将其作为字符串。

尝试以下方法:

var numberNodes = document.querySelectorAll('span[title="Numbers"]')
function giveText(me) { return me.textContent; }
Array.prototype.map.call(numberNodes, giveText).join("\n");

第一行选择文档中使用CSS查询选择器的所有节点(意味着您不需要XPath)。 第二行创建一个返回节点文本内容的函数。 第三行使用numberNodes函数映射giveText列表中的元素,生成一个数字数组,然后最后用换行符连接它们。

在此之后你可能不需要这个xmlstarlet。

答案 1 :(得分:1)

Firebug中的

$$("<CSS3 selector>")$x("<XPATH>")实际上返回一个真实的数组(不像document.querySelectorAll()或document.evaluate的结果)。所以他们更方便。

使用Firefox + Firebug:

var numbersNode = $x("//span[@title='Numbers']/text()");
var numbersText = numbersNode.map(function(numberNode) {
    return numberNode.textContent;
}).join("\n");
// Special command of Firebug to copy text into clipboard:
copy(numbersText); 

您甚至可以使用EcmaScript 6的箭头功能:

copy($x("//span[@title='Numbers']/text()").map(x => x.textContent).join("\n"));

如果您按照建议的William Narmontas选择$$('span[title="Numbers"]'),也是如此。

Florent的