Scrapy和XPath一般选择

时间:2012-10-16 16:14:09

标签: python xpath scrapy

我刚开始使用Scrapy,经历了一些示例并自己写了一个spider,但现在我一直有选择文本数据的问题。例如,我如何只选择一个表单元格中的文本,如果它不总是采用唯一格式:

<table>
 <tr>
    <td>
        <div id="somediv1">
              <span>blablabla</span>
         </div>
    </td>
    <td>
        <div id="somediv2">
              <span>text2</span>
         </div>
          <div id="somediv3">
              <span>text3</span>
         </div>

         <span>text4</span>
    </td>
 </tr>
</table>

因此,单元格内的文本将嵌套在未知标记内,我当然只想提取没有任何标记的干净文本。

1 个答案:

答案 0 :(得分:1)

使用

//table//td//text()[normalize-space()]

这将选择任何非全部空格文本节点,该节点是td的后代,它是XML文档的table元素的后代。

基于XSLT的验证

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:for-each select="//table//td//text()[normalize-space()]">
       <xsl:copy-of select="."/>
=============   
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<table>
    <tr>
        <td>
            <div id="somediv1">
                <span>blablabla</span>
            </div>
        </td>
        <td>
            <div id="somediv2">
                <span>text2</span>
            </div>
            <div id="somediv3">
                <span>text3</span>
            </div>
            <span>text4</span>
        </td>
    </tr>
</table>

评估XPath表达式,并使用视觉上与众不同的分隔符字符串将所有选定的文本节点复制到输出中:

blablabla
=============   
     text2
=============   
     text3
=============   
     text4
=============   

<强>更新

如果源XML文档位于默认命名空间中,则应更改上述XPath表达式以解释此事实:

//x:table//x:td//text()[normalize-space()

其中前缀"x"绑定到源XML文档的默认命名空间。

这是一个完整的示例,基于XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.w3.org/1999/xhtml">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:for-each select="//x:table//x:td//text()[normalize-space()]">
       <xsl:copy-of select="."/>
=============   
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档(提供的文档,但放入默认(XHTML)命名空间:

<table xmlns="http://www.w3.org/1999/xhtml">
    <tr>
        <td>
            <div id="somediv1">
                <span>blablabla</span>
            </div>
        </td>
        <td>
            <div id="somediv2">
                <span>text2</span>
            </div>
            <div id="somediv3">
                <span>text3</span>
            </div>
            <span>text4</span>
        </td>
    </tr>
</table>

再次生成相同的正确结果

blablabla
=============   
     text2
=============   
     text3
=============   
     text4
=============