在具有特定id和tr具有特定属性的表中获取td中的文本

时间:2019-03-02 12:37:03

标签: 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>   
'''

我想使用id=tab2从表的td中获取文本,其中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 1 \ ntab2 tr1 td 2 \ ntab2 tr1 td 3 \ n','\ ntab2 tr2 td   1 \ ntab2 tr2 td 2 \ n']

是否有一种更清洁的方法来获取每个td满足我在表和tr上的条件的文本?

2 个答案:

答案 0 :(得分:0)

一种更好和更清洁的访问表的方法是使用Vanilla 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 :(得分:0)

ResultSet对象可以像列表一样对待,并可以直接用于列表理解中。您可以使用嵌套列表推导来首先获取每个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']