Skip to main content
 首页 » 编程设计

python之Scrapy 和 XPath 通用选择

2025年05月04日8yxwkf

我刚刚开始使用 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> 

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

请您参考如下方法:

使用:

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

这会选择作为 td 的后代的任何非全空白文本节点,而 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" 绑定(bind)到源 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 
=============