Сначала разделяешь на строки, потом из каждой строки берёшь столбцы
>>> import lxml.html
>>>
>>> text = """
... <table>
... <tr><td>a</td><td>b</td></tr>
... <tr><td>c</td><td>d</td></tr>
... <tr><td>e</td><td>f</td></tr>
... </table>
... """
>>>
>>> doc = lxml.html.fragment_fromstring(text)
>>>
>>> out = [i.xpath('td/text()') for i in doc.xpath('//table/tr')]
>>> out
[['a', 'b'], ['c', 'd'], ['e', 'f']]
>>>
Почему не надо сразу столбцы брать - потому что в таблицах сами строки бывают разные по назначению и надо брать не все строки, а лишь некоторые. Где-то нужно провести дополнительные преобразования над строками, прежде чем брать столбцы из них. Но часто бывает так, что строки берёшь одним способом, а столбцы берёшь другим способом. Для этого и нужно разделение на этапы (сначала строки, потом столбцы).
Если же всё (и строки, и столбцы) берёшь одним способом, то ты сковываешь свои возможности. У тебя теряется вариативность применения разных методов, и ты
обязан применять к столбцам те же методы парсинга, что и к строкам. Вот чтобы этой обязанности избежать, нужно поделить парсинг на два этапа.