【问题标题】:Python Beautiful Soup parse a table with a specific IDPython Beautiful Soup 解析具有特定 ID 的表
【发布时间】:2013-10-25 13:51:37
【问题描述】:

我正在尝试从具有我知道的特定 ID 的表中获取数据。 出于某种原因,代码一直给我一个 None 结果。

从我试图解析的 HTML 代码:

<table cellspacing="0" cellpadding="3" border="0" id="ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1" style="width:100%;border-collapse:collapse;">
    <tr class="gridHeader" valign="top">
        <td class="titleGridRegNoB" align="center" valign="top"><span dir=RTL>שווי שוק (אלפי ש"ח)</span></td>
        <td class="titleGridReg" align="center" valign="top">הון רשום למסחר</td>
        <td class="titleGridReg" align="center" valign="top">שער נמוך</td><td class="titleGridReg" align="center" valign="top">שער גבוה</td>
        <td class="titleGridReg" align="center" valign="top">שער בסיס</td>
        <td class="titleGridReg" align="center" valign="top">שער פתיחה</td><td class="titleGridReg" align="center" valign="top"><span dir="rtl">שער נעילה (באגורות)</span></td>
        <td class="titleGridReg" align="center" valign="top">שער נעילה מתואם</td><td class="titleGridReg" align="center" valign="top">תאריך</td>
    </tr>
    <tr onmouseover="this.style.backgroundColor='#FDF1D7'" onmouseout="this.style.backgroundColor='#ffffff'">

...等等

我的代码:

html = br.response().read()
soup = BeautifulSoup(html)

table = soup.find(lambda tag: tag.name=='table' and tag.has_key('id') and tag['id']=="ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1")
rows = table.findAll(lambda tag: tag.name=='tr')

In [100]: print table
None

【问题讨论】:

  • 你为什么不直接使用find_all(tag, id="id_name")
  • 您在谈论行创建?不幸的是,桌子本身是空的,所以没关系..我需要先把“桌子”做好..
  • 这行table = soup.find()也是一样的
  • @aIKid table = soup.find(tag, id="ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1") 给出:NameError: name 'tag' is not defined
  • 这行得通吗?我已经添加了答案。

标签: python beautifulsoup


【解决方案1】:

来自documentation

table = soup.find('table', id="ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1")

而对于行行:

rows = table.findAll('tr')

对于编码问题,尝试从utf-8解码,然后重新编码。

html = br.response().read().decode('utf-8')
soup = BeautifulSoup(html.encode('utf-8'))

【讨论】:

  • @alKid 感谢您的帮助,但它仍然返回 None:table = soup.find('table', id="ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1") print table None 会不会是因为它是表中的表?
  • @aIKid 但问题是,他使用的是 UTF-8,所以这可能是一个问题。他的 html 中有希伯来语。
  • 请保存来自机械化浏览器的响应。 f=open('test.html','w');html = br.response().read();f.write(html),查看保存的页面。可能是您收到无效回复:)
  • 如果我没有id,但有class,如何查找表?
【解决方案2】:

改进 aiKid 的回答:

# coding=utf-8
from bs4 import BeautifulSoup

html = u"""
<table cellspacing="0" cellpadding="3" border="0" id="ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1" style="width:100%;border-collapse:collapse;">
                            <tr class="gridHeader" valign="top">
                                <td class="titleGridRegNoB" align="center" valign="top"><span dir=RTL>שווי שוק (אלפי ש"ח)</span></td><td class="titleGridReg" align="center" valign="top">הון רשום למסחר</td><td class="titleGridReg" align="center" valign="top">שער נמוך</td><td class="titleGridReg" align="center" valign="top">שער גבוה</td><td class="titleGridReg" align="center" valign="top">שער בסיס</td><td class="titleGridReg" align="center" valign="top">שער פתיחה</td><td class="titleGridReg" align="center" valign="top"><span dir="rtl">שער נעילה (באגורות)</span>
</td><td class="titleGridReg" align="center" valign="top">שער נעילה מתואם</td><td class="titleGridReg" align="center" valign="top">תאריך</td>
                            </tr><tr onmouseover="this.style.backgroundColor='#FDF1D7'" onmouseout="this.style.backgroundColor='#ffffff'">
"""

soup = BeautifulSoup(html)
print soup.find_all("table",
                    id="ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1")

由于您使用的是 UTF-8 数据,因此您需要将字符串设置为 unicode 字符串,例如 u"""(...)"""。使用 unicode 所需要做的就是:

br.response().read().decode('utf-8')

上面将为您提供一个 ASCII 字符串,您可以稍后将其编码为 un​​icode。例如,假设字符串存储在html 中,您可以使用html.encode("utf-8") 将其编码回unicode。如果您这样做,则无需将u 放在任何内容的前面。您可以再次将所有内容视为常规字符串。

【讨论】:

  • 尝试将其包装成 unicode,就像这样html = unicide(br.response(),read())
  • 还是不行。我试过了:table_id = u"""ctl00_SPWebPartManager1_g_c001c0d9_0cb8_4b0f_b75a_7cc3b6f7d790_ctl00_HistoryData1_gridHistoryData_DataGrid1""" table = soup.findall(u"""table""", id=table_id) 我得到了:TypeError: 'NoneType' object is not callable
  • @erantdo 你试过用他的推荐吗?更改此行:html = unicode(br.response(),read())
  • @erantdo 好吧,ID 中没有 unicode,所以没问题。您是否确保在文件的最顶部输入# encoding=utf-8
  • @alKid @Gamesbrainiac 我在顶部添加了这个,但它是一个评论(我正在使用 Canopy)。此外,更改为 html = unicode(br.response().read()) 会返回 UnicodeDecodeError: 'ascii' codec can't decode byte 0xd7 in position 118: ordinal not in range(128)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-21
  • 2014-12-16
  • 2019-11-23
  • 2015-11-08
  • 2011-09-27
  • 2014-04-21
  • 2018-11-26
相关资源
最近更新 更多