如何将两个表组合成一个美丽的汤对象

时间:2013-12-09 04:43:15

标签: python python-2.7 beautifulsoup

我正在查询网站并从结果页面上的表格中抓取数据。有时会有不止一张桌子(事先我不知道)。 HTML代码如下所示:

<div id="containter1" class="rank-container"
    <table class="ysr-list" id="ysr-list1">
        <thead></thead>
        <tbody>
            <tr class="name1"></tr>
            <tr class="name2"></tr>
            <tr class="name3"></tr>
        </tbody>

有时看起来像这样

<div id="containter1" class="rank-container"
    <table class="ysr-list" id="ysr-list1">
        <thead></thead>
        <tbody>
            <tr class="name1"></tr>
            <tr class="name2"></tr>
            <tr class="name3"></tr>
        </tbody>

bla bla bla

<div id="containter2" class="rank-container"
    <table class="ysr-list" id="ysr-list2">
        <thead></thead>
        <tbody>
            <tr class="name1"></tr>
            <tr class="name2"></tr>
            <tr class="name3"></tr>
        </tbody>

我目前正在做的是

Table = soup.find('table', {'id':'ysr-list1'})
然而,当有一张桌子时,这显然会错过第二张桌子。我想做的是以某种方式将表组合成一个BS对象

Table1 = soup.find('table', {'id':'ysr-list1'})
Table2 = soup.find('table', {'id':'ysr-list2'})

Table = Table1 + Table2

其中Table的类型为bs4.element.TagTable1Table2的类型),因此我可以获取给定页面上所有表的所有行由

TableRows = Table.find_all('tr')

我还想要一个优雅的建议来自动确定有id=ysr-listX个表的最佳方式,其中X是页面上的表数,并将它们全部收集到{ {1}}如上所述的对象。

谢谢

2 个答案:

答案 0 :(得分:1)

您可以将lxmlcssselect结合使用,然后使用CSS选择器 语法通过类名返回元素列表来搜索两个表。

以下是一个例子:

>>> html = open("test.html", "r").read()
>>> from lxml.html import fromstring
>>> import cssselect
>>> doc = fromstring(html)
>>> doc.cssselect("table.ysr-list")
[<Element table at 0x1044606b0>, <Element table at 0x104460710>]

答案 1 :(得分:1)

使用列表理解和findAll查找

的解决方案
  • 汤中所有table个对象的列表
  • 表对象列表中的tr列表

以下是代码:

from BeautifulSoup import BeautifulSoup as bs

input = '''<html><head><title>title</title></head>
<body>
<p>paragraph</p>
<div><div>
    <table>table1<table>inner11<table>inner12</table></table></table>
    <div><table>table2<table>inner2</table></table></div>
</div></div>
<table>table3<table>inner3</table></table>
<table>table4<table>inner4</table></table>
</html>'''
input = '''
<div id="containter1" class="rank-container"
    <table class="ysr-list" id="ysr-list1">
            <thead></thead>
         <tbody>
            <tr class="name1"></tr>
            <tr class="name2"></tr>
            <tr class="name3"></tr>
         </tbody>
    </table>

bla bla bla

<div id="containter2" class="rank-container"
    <table class="ysr-list" id="ysr-list2">
            <thead></thead>
         <tbody>
            <tr class="name1"></tr>
            <tr class="name2"></tr>
            <tr class="name3"></tr>
         </tbody>
    </table>

<div id="containter3" class="rank-container"
    <table class="ysr-list" id="ysr-list1">
            <thead></thead>
         <tbody>
            <tr class="name4"></tr>
            <tr class="name5"></tr>
            <tr class="name6"></tr>
         </tbody>
    </table>
'''
soup = bs(input)
alltables = soup.findAll("table",{'id':'ysr-list1'})
print "Number of ysr-list1 tables found : " , len(alltables)

allrows=[table.findAll('tr') for table in alltables]

allrows=[row for sublist in allrows for row in sublist]
for row in allrows:
 print row

使用Python 2.7输出:

Number of ysr-list1 tables found :  2
<tr class="name1"></tr>
<tr class="name2"></tr>
<tr class="name3"></tr>
<tr class="name4"></tr>
<tr class="name5"></tr>
<tr class="name6"></tr>