Python 使用xpath对嵌套和顺序元素进行分组

Python 使用xpath对嵌套和顺序元素进行分组,python,xpath,scrapy,Python,Xpath,Scrapy,我想使用Scrapy对页面上的重复元素进行分组,但是对于这个特定的示例没有太多的信息。也许你们中的一位能帮我做这件事 HTML 这是我希望使用Scrapy刮取的页面上的当前HTML标记: ############### # First group # ############### <table> <tbody> <tr> <td>Heading1</td> </tr> </tbo

我想使用Scrapy对页面上的重复元素进行分组,但是对于这个特定的示例没有太多的信息。也许你们中的一位能帮我做这件事


HTML

这是我希望使用Scrapy刮取的页面上的当前HTML标记:

###############
# First group #
###############
<table>
  <tbody>
    <tr>
      <td>Heading1</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>
        <table>
          <tbody>
            <tr>
              <td><a href="Foo1URL">Foo1</a></td>
              <td>Bar1</td>
            </tr>
            <tr>
              <td><a href="Foo2URL">Foo2</a></td>
              <td>Bar2</td>
            </tr>
          </tbody>
        </table>
        <table>
          <tbody>
            <tr>
              <td><a href="Foo3URL">Foo3</a></td>
              <td>Bar3</td>
            </tr>
            <tr>
              <td><a href="Foo4URL">Foo4</a></td>
              <td>Bar4</td>
            </tr>
          </tbody>
        </table>
        ... 
    </td>
    <td>
        <table>
          <tbody>
            <tr>
              <td>Sub-Heading1</td>
            </tr>
            <tr>
              <td>Name1</td>
              <td>1</td>
              <td>1</td>
              <td>1</td>
            </tr>
            <tr>
              <td>Name2</td>
              <td>2</td>
              <td>2</td>
              <td>2</td>
            </tr>
            <tr>
              <td>Name3</td>
              <td>3</td>
              <td>3</td>
              <td>3</td>
            </tr>  
            ...      
          </tbody>
        </table>
    </td>
    </tr>
  </tbody>
</table>
################
# Second group #
################
<table>
  <tbody>
    <tr>
      <td>Heading2</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>
        <table>
          <tbody>
            <tr>
              <td><a href="Foo5URL">Foo5</a></td>
              <td>Bar5</td>
            </tr>
            <tr>
              <td><a href="Foo6URL">Foo6</a></td>
              <td>Bar6</td>
            </tr>
          </tbody>
        </table>
        <table>
          <tbody>
            <tr>
              <td><a href="Foo7URL">Foo7</a></td>
              <td>Bar7</td>
            </tr>
            <tr>
              <td><a href="Foo8URL">Foo8</a></td>
              <td>Bar8</td>
            </tr>
          </tbody>
        </table>
        ...
    </td>
    <td>
        <table>
          <tbody>
            <tr>
              <td>Sub-Heading2</td>
            </tr>
            <tr>
              <td>Name4</td>
              <td>4</td>
              <td>4</td>
              <td>4</td>
            </tr>
            <tr>
              <td>Name5</td>
              <td>5</td>
              <td>5</td>
              <td>5</td>
            </tr>
            <tr>
              <td>Name6</td>
              <td>6</td>
              <td>6</td>
              <td>6</td>
            </tr>  
            ...      
          </tbody>
        </table>
    </td>
    </tr>
  </tbody>
</table>
################
# Third group #
################

# ... and so on
该结构在页面和其他页面上重复自身,因此一个页面上可以有X个这样的组


示例刮取数据

这是我想在页面上刮取的内容:

[ (Heading1, Foo1, Foo1URL, Bar1, Foo2, Foo2URL, Bar2),
  (Heading1, Foo3, Foo3URL, Bar3, Foo4, Foo4URL, Bar4),
  ... 
  (Heading2, Foo5, Foo5URL, Bar5, Foo6, Foo6URL, Bar6),
  (Heading2, Foo7, Foo7URL, Bar8, Foo8, Foo8URL, Bar8),
  ... ]
然后,对于副标题:

[ (Heading1, Sub-Heading1, Name1, 1, 1, 1),
  (Heading1, Sub-Heading1, Name2, 2, 2, 2),
  (Heading1, Sub-Heading1, Name3, 3, 3, 3),
  ...
  (Heading2, Sub-Heading2, Name4, 4, 4, 4),
  (Heading2, Sub-Heading2, Name5, 5, 5, 5),
  (Heading2, Sub-Heading2, Name6, 6, 6, 6),
  ... ]


在这种情况下,当很难区分html条目时,您可以尝试使用元素位置,这意味着:

item = SomeItem()
item2 = SomeOtherItem()
for idx,t in enumerate(sel.xpath('/html/body/table')):
    if not idx % 2:
        item.field1 = t.xpath('tbody/tr/td/text()').extract()[0]
    else:
        content = t.xpath('tbody/tr/td[1]')
        item.field2 = content.xpath('table/tbody/tr/td[1]/a/@href).extract()[0]
        item.field3 = content.xpath('table/tbody/tr/td[2]/text()).extract()[0]
        sub_heading = t.xpath('tbody/tr/td[2]')
        item2.field1 = heading.xpath(...)
        ...

希望这有帮助。

有人能帮上忙吗?谢谢你的回复。这是一个好的方向。我是否能够使用
标题1
作为参考来检查我所在的表格?就像页面上可能有其他一些表一样,如果我可以说检查表是否在标题之后,我认为它在xpath中被称为同级表,但我认为这仅适用于嵌套表,这将非常好。此外,每个表上可能有
x
行数,那么您建议如何处理该表?谢谢你抽出时间!对于您的第一个问题,请尝试
//td[text()='Heading1']
从这里开始,您可以
///td[text()='Heading1']/../../following sibling::table
等。谢谢您!我不知道你会像那样死灰复燃!我似乎对这个解决方案有一个问题,因为页面上的其他表在页面中间(不遵循这个结构),然后组再次继续。我想我需要了解如何将标题和下一张表组合在一起。对这个家伙有什么帮助吗?
item = SomeItem()
item2 = SomeOtherItem()
for idx,t in enumerate(sel.xpath('/html/body/table')):
    if not idx % 2:
        item.field1 = t.xpath('tbody/tr/td/text()').extract()[0]
    else:
        content = t.xpath('tbody/tr/td[1]')
        item.field2 = content.xpath('table/tbody/tr/td[1]/a/@href).extract()[0]
        item.field3 = content.xpath('table/tbody/tr/td[2]/text()).extract()[0]
        sub_heading = t.xpath('tbody/tr/td[2]')
        item2.field1 = heading.xpath(...)
        ...