def _parse_thead_tbody_tfoot(self, table_html):
        """
        Given a table, return parsed header, body, and foot.

        Parameters
        ----------
        table_html : node-like

        Returns
        -------
        tuple of (header, body, footer), each a list of list-of-text rows.

        Notes
        -----
        Header and body are lists-of-lists. Top level list is a list of
        rows. Each row is a list of str text.

        Logic: Use <thead>, <tbody>, <tfoot> elements to identify
               header, body, and footer, otherwise:
               - Put all rows into body
               - Move rows from top of body to header only if
                 all elements inside row are <th>
               - Move rows from bottom of body to footer only if
                 all elements inside row are <th>
        """

        header_rows = self._parse_thead_tr(table_html)
        body_rows = self._parse_tbody_tr(table_html)
        footer_rows = self._parse_tfoot_tr(table_html)

        def row_is_all_th(row):
            return all(self._equals_tag(t, 'th') for t in
                       self._parse_td(row))

        if not header_rows:
            # The table has no <thead>. Move the top all-<th> rows from
            # body_rows to header_rows. (This is a common case because many
            # tables in the wild have no <thead> or <tfoot>
            while body_rows and row_is_all_th(body_rows[0]):
                header_rows.append(body_rows.pop(0))

        header = self._expand_colspan_rowspan(header_rows)
        body = self._expand_colspan_rowspan(body_rows)
        footer = self._expand_colspan_rowspan(footer_rows)

        return header, body, footer
def _parse_thead_tbody_tfoot ( self , table_html ) : header_rows = self . _parse_thead_tr ( table_html ) body_rows = self . _parse_tbody_tr ( table_html ) footer_rows = self . _parse_tfoot_tr ( table_html ) def row_is_all_th ( row ) : return all ( self . _equals_tag ( t , 'th' ) for t in self . _parse_td ( row ) ) if not header_rows : while body_rows and row_is_all_th ( body_rows [ 0 ] ) : header_rows . append ( body_rows . pop ( 0 ) ) header = self . _expand_colspan_rowspan ( header_rows ) body = self . _expand_colspan_rowspan ( body_rows ) footer = self . _expand_colspan_rowspan ( footer_rows ) return header , body , footer
Given a table, return parsed header, body, and foot.

        Parameters
        ----------
        table_html : node-like

        Returns
        -------
        tuple of (header, body, footer), each a list of list-of-text rows.

        Notes
        -----
        Header and body are lists-of-lists. Top level list is a list of
        rows. Each row is a list of str text.

        Logic: Use <thead>, <tbody>, <tfoot> elements to identify
               header, body, and footer, otherwise:
               - Put all rows into body
               - Move rows from top of body to header only if
                 all elements inside row are <th>
               - Move rows from bottom of body to footer only if
                 all elements inside row are <th>