【问题标题】:how do we select the child element tbody after extracting the entire html?提取整个html后如何选择子元素tbody?
【发布时间】:2019-06-19 08:13:21
【问题描述】:

我仍然是一个尝试学习beautifulsoup 的python 菜鸟。我查看了堆栈上的解决方案但没有成功请帮助我更好地理解这一点。 我已经提取了如下所示的html

<table cellspacing="0" id="ContentPlaceHolder1_dlDetails" 
     style="width:100%;border-collapse:collapse;">
     <tbody><tr>
     <td>
     <table border="0" cellpadding="5" cellspacing="0" width="70%">
     <tbody><tr>
     <td> </td>
     <td> </td>
     </tr>
     <tr>
     <td bgcolor="#4F95FF" class="listhead" width="49%">Location:</td>
     <td bgcolor="#4F95FF" class="listhead" width="51%">On Site </td>
     </tr>
     <tr>
     <td class="listmaintext">ATM ID: </td>
     <td class="listmaintext">DAGR00401111111</td>
     </tr>
     <tr>
     <td class="listmaintext">ATM Centre:</td>
     <td class="listmaintext"></td>
     </tr>
     <tr>
     <td class="listmaintext">Site Location: </td>
     <td class="listmaintext">ADA Building - Agra</td>
     </tr>

我试图解析 find_all('tbody') 但不成功

        #table = bs.find("table", {"id": "ContentPlaceHolder1_dlDetails"})
        html = browser.page_source
        soup = bs(html, "lxml")
        table = soup.find_all('table', {'id':'ContentPlaceHolder1_dlDetails'})
        table_body = table.find('tbody')
        rows = table.select('tr')
        for row in rows:
            cols = row.find_all('td')
            cols = [ele.text.strip() for ele in cols]
            data.append([ele for ele in cols if ele])values

我正在尝试将值保存在“listmaintext”类中

错误信息 AttributeError: ResultSet object has no attribute 'find'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?

【问题讨论】:

  • 如果您指定了所需的输出格式,这将有所帮助。上面你似乎想要一个列表。
  • 所需的输出格式为 ATM ID:DAGR00401111111 ATM 中心:站点位置:ADA 大楼 - Agra Link 分支:Sol ID:54000 州:北方邦区:阿格拉 场外地址:场内地址:联合印度银行,Adra Development Authority- Agra Branch, Agra Development Authority, Agra, Jaipur House, Loha Mandi, Uttar Pradesh - 282010 密码:在 csv 或 json 中,因为我有多个具有相同标题的 html

标签: python python-3.x html-table beautifulsoup


【解决方案1】:

使用 next_sibling 的另一种方法

from bs4 import BeautifulSoup as bs

html ='''
<html>
<table cellspacing="0" id="ContentPlaceHolder1_dlDetails" 
     style="width:100%;border-collapse:collapse;">
     <tbody><tr>
     <td>
     <table border="0" cellpadding="5" cellspacing="0" width="70%">
     <tbody><tr>
     <td> </td>
     <td> </td>
     </tr>
     <tr>
     <td bgcolor="#4F95FF" class="listhead" width="49%">Location:</td>
     <td bgcolor="#4F95FF" class="listhead" width="51%">On Site </td>
     </tr>
     <tr>
     <td class="listmaintext">ATM ID: </td>
     <td class="listmaintext">DAGR00401111111</td>
     </tr>
     <tr>
     <td class="listmaintext">ATM Centre:</td>
     <td class="listmaintext"></td>
     </tr>
     <tr>
     <td class="listmaintext">Site Location: </td>
     <td class="listmaintext">ADA Building - Agra</td>
     </tr>
</html>'''

soup = bs(html, 'lxml')
data = [' '.join((item.text, item.next_sibling.next_sibling.text)) for item in soup.select('#ContentPlaceHolder1_dlDetails tr .listmaintext:first-child') if item.text !='']
print(data)

【讨论】:

  • 我尝试了上述方法,我似乎得到一个空数组我做错了什么? html = browser.page_source soup = bs(html, "lxml") data = [' '.join((item.text, item.next_sibling.next_sibling.text)) for item in soup.select('#ContentPlaceHolder1_dlDetails tr .listmaintext :first-child') if item.text !=''] print(data)
  • 你能提供源网址吗?我也在使用 bs4 4.7.1,但您似乎没有收到与版本相关的错误,是吗?
  • 不,我有相同的版本。网址eremit.unionbankofindia.co.in/livebranch/ATMList.aspx
  • 搜索印度并点击第一个链接。我正在尝试提取所有 188 页的所有信息
  • 它对我有用。您是否需要等待条件来确保数据存在?如果我只是传输页面 html,我会得到:['ATM ID:DAGR00401111111','ATM 中心:','站点位置:ADA 大楼 - 阿格拉','链接分支:','Sol ID:54000','州:北方Pradesh', 'District: Agra', 'Off Site Address: ', 'On Site Address: Union Bank of India, Adra Development Authority- Agra Branch, Agra Development Authority, Agra, Jaipur House, Loha Mandi, Uttar Pradesh - 282010' , '密码:']
【解决方案2】:
from bs4 import BeautifulSoup

data = '''<table cellspacing="0" id="ContentPlaceHolder1_dlDetails"
     style="width:100%;border-collapse:collapse;">
     <tbody><tr>
     <td>
     <table border="0" cellpadding="5" cellspacing="0" width="70%">
     <tbody><tr>
     <td> </td>
     <td> </td>
     </tr>
     <tr>
     <td bgcolor="#4F95FF" class="listhead" width="49%">Location:</td>
     <td bgcolor="#4F95FF" class="listhead" width="51%">On Site </td>
     </tr>
     <tr>
     <td class="listmaintext">ATM ID: </td>
     <td class="listmaintext">DAGR00401111111</td>
     </tr>
     <tr>
     <td class="listmaintext">ATM Centre:</td>
     <td class="listmaintext"></td>
     </tr>
     <tr>
     <td class="listmaintext">Site Location: </td>
     <td class="listmaintext">ADA Building - Agra</td>
     </tr>'''

soup = BeautifulSoup(data, 'lxml')

s = soup.select('.listmaintext')
for td1, td2 in zip(s[::2], s[1::2]):
    print('{} [{}]'.format(td1.text.strip(), td2.text.strip()))

打印:

ATM ID: [DAGR00401111111]
ATM Centre: []
Site Location: [ADA Building - Agra]

【讨论】:

  • 非常感谢。你能指点我解释为什么我们使用``` (s[::2], s[1::2]) ``` 我真的很想学习的资源。提前谢谢你
  • @Amir 这是 Python 的切片表示法 (stackoverflow.com/questions/509211/understanding-slice-notation) [::2] -> 表示从列表中每隔一个项目(从 0 开始)[1::2] -> 每隔一秒从索引 1 开始的项目
  • 感谢@Andrej 十亿。那篇文章真的很有帮助。
猜你喜欢
  • 1970-01-01
  • 2013-03-25
  • 2012-12-25
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 2011-06-04
相关资源
最近更新 更多