【问题标题】:BeautifulSoup4: parsing bad formatted HTMLBeautifulSoup4:解析格式错误的 HTML
【发布时间】:2020-04-05 00:04:00
【问题描述】:

我正在尝试解析一组表格,其中列出了有关智能手机的信息。例如this link。我只是想获得 4 个我需要的特定字段,而获得第四个字段让我发疯。

似乎 HTML 格式错误。我们有几个表按顺序放置到 html 中。前5个还可以,但是第六个表以</td></tr></table>结尾,关闭了一个<td>和一个<tr>,它们以前没有打开过(或者至少我认为这是问题所在):

<table cellspacing="0">
<tr>
<th rowspan="5" scope="row">Memory</th>
<td class="ttl"><a href="glossary.php3?term=memory-card-slot">Card slot</a></td>


<td class="nfo" data-spec="memoryslot">microSD, up to 256 GB (uses shared SIM slot)</td></tr>



<tr>
<td class="ttl"><a href="glossary.php3?term=dynamic-memory">Internal</a></td>
<td class="nfo" data-spec="internalmemory">64GB 6GB RAM, 128GB 6GB RAM, 128GB 8GB RAM, 256GB 8GB RAM</td>
</tr>


<tr><td class="ttl">&nbsp;</td><td class="nfo" data-spec="memoryother">UFS2.1</td></tr>

</td>
</tr>
</table>

另外,第七张表的列表很糟糕,但我想这对bs4来说应该不是问题。

因此,如果我尝试使用 CSS 选择器从表 7 到最后一个表中获取任何值,选择器将返回 None。事实上,如果我只是使用一个选择器来获取所有的表,它只是选择了前 6 个表:

        dsoup = BeautifulSoup(dr.content, 'html.parser')
        dsel = dsoup.select('#specs-list > table')
        print('Found {} tables'.format(len(dsel)))  # Prints 6 tables
        dsel = dsoup.select_one('#specs-list > table:nth-of-type(10) > tbody > tr:nth-of-type(3) > td.nfo')
        print(dsel.text.split('\n')) # None

所以问题是,有没有办法解析像这样的格式错误的 HTML 的情况,还是不可能?

【问题讨论】:

    标签: python html beautifulsoup css-selectors


    【解决方案1】:

    不要使用'html.parser',而是使用'html5lib' - 它根据(大部分)HTML5 规则进行解析:

    import requests
    from bs4 import BeautifulSoup
    
    url = 'https://www.gsmarena.com/xiaomi_redmi_note_8_pro-9812.php'
    
    soup = BeautifulSoup(requests.get(url).text, 'html5lib')
    
    for th in soup.select('#specs-list th'):
        table = th.find_previous('table')
        for ttl in table.select('.ttl'):
            print('{:<20} {:<20} {}'.format( th.text, ttl.text, ttl.find_next_sibling('td', {'class':'nfo'}).get_text(strip=True, separator=' ')) )
    

    打印:

    Network              Technology           GSM / HSPA / LTE
    Network              2G bands             GSM 850 / 900 / 1800 / 1900 - SIM 1 & SIM 2
    Network              3G bands             HSDPA 850 / 900 / 1900 / 2100
    Network              4G bands             LTE band 1(2100), 3(1800), 5(850), 7(2600), 8(900), 40(2300), 41(2500)
    Network              Speed                HSPA 42.2/5.76 Mbps, LTE-A
    Launch               Announced            2019, August
    Launch               Status               Available. Released 2019, September
    Body                 Dimensions           161.4 x 76.4 x 8.8 mm (6.35 x 3.01 x 0.35 in)
    Body                 Weight               200 g (7.05 oz)
    Body                 Build                Front/back glass (Gorilla Glass 5)
    Body                 SIM                  Hybrid Dual SIM (Nano-SIM, dual stand-by)
    Display              Type                 IPS LCD capacitive touchscreen, 16M colors
    Display              Size                 6.53 inches, 104.7 cm 2 (~84.9% screen-to-body ratio)
    Display              Resolution           1080 x 2340 pixels, 19.5:9 ratio (~395 ppi density)
    Display              Protection           Corning Gorilla Glass 5
    Display                                   500 nits max brightness HDR
    Platform             OS                   Android 9.0 (Pie); MIUI 10
    Platform             Chipset              Mediatek Helio G90T (12nm)
    
    ... and so on.
    

    【讨论】:

      猜你喜欢
      • 2018-08-28
      • 1970-01-01
      • 2012-12-16
      • 2018-12-18
      • 2019-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多