首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从非语义表中的header in header中获取同级

从非语义表中的header in header中获取同级
EN

Stack Overflow用户
提问于 2012-12-29 03:07:52
回答 1查看 1.1K关注 0票数 2

使用Scrapy,我想解析一个包含非常不具语义的表格的网页。我正在寻找的是一个“打印每个跟在后面的兄弟,直到你遇到以下元素”--XPath-query。

代码语言:javascript
复制
<table>
    <tr>
        <th>Title</th>
        <th>Name</th>
        <th>Comment</th>
        <th>Note</th>
    </tr>
    <tr style="background-color:#CCDDEF;">
        <td colspan="4"> <b>HEADER1</b></td>
    </tr>
    <tr>
        <td>Title1.1</td>
        <td>-</td>
        <td>Info1.1</td>
        <td></td>
    </tr>
    <tr style="background-color:#CCDDEF;">
        <td colspan="4"> <b>HEADER2</b></td>
    </tr>
    <tr>
        <td>Title2.1</td>
        <td>Name2.1</td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>Title2.2</td>
        <td>Name2.2</td>
        <td>Info2.2</td>
        <td></td>
    </tr>
    <tr style="background-color:#CCDDEF;">
        <td colspan="4"> <b>HEADER3</b></td>
    </tr>
    <tr>
        <td>Title3.1</td>
        <td>Name3.1</td>
        <td></td>
        <td></td>
    </tr>
</table>

我想将每个标题、名称、注释和备注分组到每个标题下。我尝试了各种XPaths (使用following-siblingpreceding-siblingcount的变体),但我要么什么都得不到,要么什么都得不到,或者每个不是头的tr都得不到。

我目前正在使用//tr[@style]//tr[td[@colspan="4"]]获取标题。

下面是我的Scrapy-spider中的解析函数(它打印标题和所有非标题的tr):

代码语言:javascript
复制
def parse(self, response):
    hxs = HtmlXPathSelector(response)
    sites = hxs.select('//*[@id="content-text"]//tr[td[@colspan="4"]]')
    for site in sites:
        print site.select('./td/b/text()').extract()
        print site.select('./following-sibling::tr[not(td[@colspan])]')
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-29 04:02:31

This XPath expression

代码语言:javascript
复制
/*/tr[@style or td[@colspan='4']][1]/following-sibling::tr
       [count(. | /*/tr[@style or td[@colspan='4']][2]/preceding-sibling::tr)
       =
        count(/*/tr[@style or td[@colspan='4']][2]/preceding-sibling::tr)
       ]

选择位于第一个和第二个tr 之间的所有headers元素

代码语言:javascript
复制
<tr>
   <td>Title1.1</td>
   <td>-</td>
   <td>Info1.1</td>
   <td/>
</tr>

要选择第k个和第(K+1)个头之间的所有tr元素,只需在上面的表达式中将1替换为K (编号),将2替换为K+1 (编号)。

基于XSLT的验证

代码语言:javascript
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <xsl:copy-of select=
     "/*/tr[@style or td[@colspan='4']][1]/following-sibling::tr
             [count(. | /*/tr[@style or td[@colspan='4']][2]/preceding-sibling::tr)
             =
              count(/*/tr[@style or td[@colspan='4']][2]/preceding-sibling::tr)
             ]
     "/>
 </xsl:template>
</xsl:stylesheet>

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

代码语言:javascript
复制
<table>
    <tr>
        <th>Title</th>
        <th>Name</th>
        <th>Comment</th>
        <th>Note</th>
    </tr>
    <tr style="background-color:#CCDDEF;">
        <td colspan="4">
            <b>HEADER1</b>
        </td>
    </tr>
    <tr>
        <td>Title1.1</td>
        <td>-</td>
        <td>Info1.1</td>
        <td></td>
    </tr>
    <tr style="background-color:#CCDDEF;">
        <td colspan="4">
            <b>HEADER2</b>
        </td>
    </tr>
    <tr>
        <td>Title2.1</td>
        <td>Name2.1</td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>Title2.2</td>
        <td>Name2.2</td>
        <td>Info2.2</td>
        <td></td>
    </tr>
    <tr style="background-color:#CCDDEF;">
        <td colspan="4">
            <b>HEADER3</b>
        </td>
    </tr>
    <tr>
        <td>Title3.1</td>
        <td>Name3.1</td>
        <td></td>
        <td></td>
    </tr>
</table>

计算Xpath表达式,并将选定节点复制到输出:

代码语言:javascript
复制
<tr>
   <td>Title1.1</td>
   <td>-</td>
   <td>Info1.1</td>
   <td/>
</tr>

说明

这是Kayessian (在Michael Kay博士之后)公式在节点集相交中的一个简单应用:

代码语言:javascript
复制
$ns1[count(.|$ns2) = count($ns2)]

在这种特殊情况下,我们将$ns1替换为:

代码语言:javascript
复制
/*/tr[@style or td[@colspan='4']][1]/following-sibling::tr

我们将$ns2替换为:

代码语言:javascript
复制
/*/tr[@style or td[@colspan='4']][2]/preceding-sibling::tr
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14074462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档