получить текст в td ‘s в таблице с определенным идентификатором и tr с определенным атрибутом

#html #python-3.x #beautifulsoup

#HTML #python-3.x #beautifulsoup

Вопрос:

Учитывая html, подобный этому:

     page_html = '''
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <div id="div1">
            <h1>h1 text</h1>
            <div id="div div1">text div div1
            </div>
            <p>text in p</p>
            <table id="tab1" border="1">
                <tr id="tab1 tr1" class="class1">
                    <td><a href="/info/tab1/tr1/td1">tab1 tr1 td 1</a></td>
                    <td><a href="/info/tab1/tr1/td2">tab1 tr1 td 2</a></td>
                    <td><a href="/info/tab1/tr1/td3">tab1 tr1 td 3</a></td>
                </tr>
                <tr id="tab1 tr2" class="class1">
                    <td><a href="/info/tab1/tr2/td1">tab1 tr2 td 1</a></td>
                    <td><a href="/info/tab1/tr2/td2">tab1 tr2 td 2</a></td>
                </tr>
                <tr id="tab1 tr3" class="class2">
                    <td><a href="/info/tab1/tr3/td1">tab1 tr3 td 1</a></td>
                    <td><a href="/info/tab1/tr3/td2">tab1 tr3 td 2</a></td>
                </tr>
            </table>
            <table id="tab2" border="1">
                <tr id="tab2 tr1" class="class2">
                    <td><a href="/info/tab2/tr1/td1">tab2 tr1 td 1</a></td>
                    <td><a href="/info/tab2/tr1/td2">tab2 tr1 td 2</a></td>
                    <td><a href="/info/tab2/tr1/td3">tab2 tr1 td 3</a></td>
                </tr>
                <tr id="tab2 tr2" class="class2">
                    <td><a href="/info/tab2/tr2/td1">tab2 tr2 td 1</a></td>
                    <td><a href="/info/tab2/tr2/td2">tab2 tr2 td 2</a></td>
                </tr>
                <tr id="tab2 tr3" class="class3">
                    <td><a href="/info/tab2/tr3/td1">tab2 tr3 td 1</a></td>
                    <td><a href="/info/tab2/tr3/td2">tab2 tr3 td 2</a></td>
                </tr>
            </table>
        </div>
</body>
</html>   
'''
  

Я хотел бы получить текст из td в таблице с, id=tab2 где tr имеют атрибут class=class2 , соответствующий:

             <tr id="tab2 tr1" class="class2">
                <td><a href="/info/tab2/tr1/td1">tab2 tr1 td 1</a></td>
                <td><a href="/info/tab2/tr1/td2">tab2 tr1 td 2</a></td>
                <td><a href="/info/tab2/tr1/td3">tab2 tr1 td 3</a></td>
            </tr>
            <tr id="tab2 tr2" class="class2">
                <td><a href="/info/tab2/tr2/td1">tab2 tr2 td 1</a></td>
                <td><a href="/info/tab2/tr2/td2">tab2 tr2 td 2</a></td>
            </tr>
  

Мое частичное решение таково:

 from bs4 import BeautifulSoup

bsobj = BeautifulSoup(page_html)
res = bsobj.find('table', id='tab2').findAll('tr', {'class':'class2'})
  

но я не могу извлечь текст.

Попытка понимания списка:

 [td.text for td in res]
  

получает общий (правильный) результат, но в виде списка двух tr и с аномальным n значением, то есть:

[‘ntab2 tr1 td 1ntab2 tr1 td 2ntab2 tr1 td 3 n’, ‘ntab2 tr2 td 1ntab2 tr2 td 2n’]

Есть ли более чистый способ получить текст для каждого td, удовлетворяющий моим условиям для table и tr?

Ответ №1:

Объекты результирующего набора могут обрабатываться как список и использоваться непосредственно для понимания списка. Вы можете использовать понимание вложенного списка, чтобы сначала получить все tr , а затем все td из каждого из tr без сохранения промежуточных результатов.

 from bs4 import BeautifulSoup
bsobj = BeautifulSoup(page_html,'html.parser')
res = [td.text for tr in bsobj.find('table', id='tab2').findAll('tr', {'class':'class2'}) for td in tr.findAll('td')]
print(res)
  

Вывод

 ['tab2 tr1 td 1', 'tab2 tr1 td 2', 'tab2 tr1 td 3', 'tab2 tr2 td 1', 'tab2 tr2 td 2']
  

Ответ №2:

Лучший и более чистый способ доступа к таблице — использовать ванильный JavaScript.

Прежде всего, вам лучше добавить id в свой <table id="myTable"> элемент, чтобы избежать конфликтов.

Вот способ прочитать все <td> из элемента таблицы с помощью <tr>

 let table = document.getElementById('myTable');
let trs = Array.from(table.getElementsByTagName('tr'));

trs.forEach(tr => {
  let tds = Array.from(table.getElementsByTagName('td'));

  tds.forEach(td => {
    console.log(td.innerHTML);
  })
})
  

Жить в действии — https://jsitor.com/A3cx88q5h

Комментарии:

1. Возможно, я не совсем понял язык. Мне интересны решения на python 3. В любом случае, спасибо.