【问题标题】:bs4 Attribute Error while scraping table python刮表python时bs4属性错误
【发布时间】:2021-07-17 21:27:06
【问题描述】:

我正在尝试使用 bs4 抓取表格。但是每当我遍历 <tbody> 元素时,我都会收到以下错误:Traceback (most recent call last): File "f:\Python Programs\COVID-19 Notifier\main.py", line 28, in <module> for tr in soup.find('tbody').findAll('tr'): AttributeError: 'NoneType' object has no attribute 'findAll'

我是 bs4 的新手,之前也曾多次遇到此错误。这是我正在使用的代码。任何帮助将不胜感激,因为这是要在比赛中提交的官方项目,并且截止日期已近。提前致谢。还有beautifulsoup4=4.8.2bs4==0.0.4soupsieve==2.0

我的代码:

from plyer import notification
import requests
from bs4 import BeautifulSoup
import time

def notifyMe(title, message):
    notification.notify(
    title = title,
    message = message,
    app_icon = ".\\icon.ico",
    timeout = 6
    )


def getData(url):
    r = requests.get(url)
    return r.text


if __name__ == "__main__":
    while True:
        # notifyMe("Harry", "Lets stop the spread of this virus together")
        myHtmlData = getData('https://www.mohfw.gov.in/')

        soup = BeautifulSoup(myHtmlData, 'html.parser')
        #print(soup.prettify())
        myDataStr = ""
        for tr in soup.find('tbody').find_all('tr'):
            myDataStr += tr.get_text()
        myDataStr = myDataStr[1:]
        itemList = myDataStr.split("\n\n")
        print(itemList)
    
        states = ['Chandigarh', 'Telengana', 'Uttar Pradesh']
        for item in itemList[0:22]:
            dataList = item.split('\n')
            if dataList[1] in states: 
                nTitle = 'Cases of Covid-19'
                nText = f"State {dataList[1]}\nIndian : {dataList[2]} & Foreign : {dataList[3]}\nCured :  {dataList[4]}\nDeaths :  {dataList[5]}"
            notifyMe(nTitle, nText)
            time.sleep(2)
        time.sleep(3600)
    

【问题讨论】:

标签: web-scraping beautifulsoup html-table attributeerror python-3.9


【解决方案1】:

这行引发了错误:

for tr in soup.findAll('tbody').findAll('tr'):

您只能在单个标签上调用find_all,而不是另一个find_all 返回的结果集。 (findAllfind_all 相同——后者更适合使用,因为它符合Python PEP 8 styling standard

根据the documentation

find_all() 方法查看标签的后代并检索与您的过滤器匹配的所有后代。

如果您要遍历单个表,只需将第一个 findAll 替换为 find。如果有多个表,将结果集存储在一个变量中并循环遍历它,您可以将findAll应用于单个标签。

这应该可以解决它:

for tr in soup.find('tbody').find_all('tr'):

多个表:

tables = soup.find_all('tbody')
for table in tables:
    for tr in table.find_all('tr'):
        ...

【讨论】:

  • 试过你的答案...现在我得到了这个:Traceback (most recent call last): File "f:\Python Programs\COVID-19 Notifier\main.py", line 28, in <module> for tr in soup.find('tbody').findAll('tr'): AttributeError: 'NoneType' object has no attribute 'findAll'
【解决方案2】:

这里有几个问题。

  1. <tbody> 标记位于 html 的 cmets 内。 BeautifulSoup 会跳过 cmets,除非您专门拉取这些。
  2. 为什么要使用getData() 函数?这只是一行,为什么不把它放到代码中。额外的功能并没有真正提高代码的效率或可读性。
  3. 即使你拉出 tbody> 标签,你的 dataList 也没有 6 个项目(你调用 dataList[5],它会抛出错误)。我调整了它,但我不知道这些是否是正确的数字。我不知道每个 vlaues 代表什么,所以你可能需要解决这个问题。您要提取的数据的标题是 ['S. No.','Name of State / UT','Active Cases*','Cured/Discharged/Migrated*','Deaths**'],所以我不知道 Indian : {dataList[2]} & Foreign : 应该是什么。
  4. 我不知道这些数字代表什么,但它是正确的数据吗?看起来您可以提取新数据 here,但它与 <tbody> 中的数字不同

那么,这里是获取其他数据源...也许更准确?

import requests
import pandas as pd

jsonData = requests.get('https://www.mohfw.gov.in/data/datanew.json').json()
df = pd.DataFrame(jsonData)

输出:

print(df.to_string())
      sno                                state_name   active  positive     cured   death new_active new_positive new_cured new_death state_code
0       2               Andaman and Nicobar Islands      153      5527      5309      65        146         5569      5358        65         35
1       1                            Andhra Pradesh    66944    997462    922977    7541      74231      1009228    927418      7579         28
2       3                         Arunachal Pradesh      380     17296     16860      56        453        17430     16921        56         12
3       4                                     Assam    11918    231069    217991    1160      13942       233453    218339      1172         18
4       5                                     Bihar    69869    365770    293945    1956      76420       378442    300012      2010         10
5       6                                Chandigarh     4273     36404     31704     427       4622        37232     32180       430         04
6       7                              Chhattisgarh   121555    605568    477339    6674     123479       622965    492593      6893         22
7       8  Dadra and Nagar Haveli and Daman and Diu     1668      5910      4238       4       1785         6142      4353         4         26
8      10                                     Delhi    91618    956348    851537   13193      92029       980679    875109     13541         07
9      11                                       Goa    10228     72224     61032     964      11040        73644     61628       976         30
10     12                                   Gujarat    92084    453836    355875    5877     100128       467640    361493      6019         24
11     13                                   Haryana    58597    390989    328809    3583      64057       402843    335143      3643         06
12     14                          Himachal Pradesh    11859     82876     69763    1254      12246        84065     70539      1280         02
13     15                         Jammu and Kashmir    16094    154407    136221    2092      16993       156344    137240      2111         01
14     16                                 Jharkhand    40942    184951    142294    1715      43415       190692    145499      1778         20
15     17                                 Karnataka   196255   1247997   1037857   13885     214330      1274959   1046554     14075         29
16     18                                    Kerala   156554   1322054   1160472    5028     179311      1350501   1166135      5055         32
17     19                                    Ladakh     2041     12937     10761     135       2034        13089     10920       135         37
18     20                               Lakshadweep      803      1671       867       1        920         1805       884         1         31
19     21                            Madhya Pradesh    84957    459195    369375    4863      87640       472785    380208      4937         23
20     22                               Maharashtra   701614   4094840   3330747   62479     693632      4161676   3404792     63252         27
21     23                                   Manipur      513     30047     29153     381        590        30151     29180       381         14
22     24                                 Meghalaya     1133     15488     14198     157       1238        15631     14236       157         17
23     25                                   Mizoram      608      5220      4600      12        644         5283      4627        12         15
24     26                                  Nagaland      384     12800     12322      94        457        12889     12338        94         13
25     27                                    Odisha    32963    388479    353551    1965      36718       394694    356003      1973         21
26     28                                Puducherry     5923     50580     43931     726       6330        51372     44314       728         34
27     29                                    Punjab    40584    319719    270946    8189      43943       326447    274240      8264         03
28     30                                 Rajasthan   107157    467875    357329    3389     117294       483273    362526      3453         08
29     31                                    Sikkim      640      6970      6193     137        693         7037      6207       137         11
30     32                                Tamil Nadu    89428   1037711    934966   13317      95048      1051487    943044     13395         33
31     34                                 Telengana    52726    379494    324840    1928      58148       387106    326997      1961         36
32     33                                   Tripura      563     34302     33345     394        645        34429     33390       394         16
33     35                               Uttarakhand    26980    138010    109058    1972      29949       142349    110379      2021         05
34     36                             Uttar Pradesh   259810    976765    706414   10541     273653      1013370    728980     10737         09
35     37                               West Bengal    68798    700904    621340   10766      74737       713780    628218     10825         19
36  11111                                            2428616  16263695  13648159  186920    2552940     16610481  13867997    189544       

这是您将 cmets 拉出的代码

代码:

import requests
from bs4 import BeautifulSoup, Comment
import time

def notifyMe(title, message):
    notification.notify(
    title = title,
    message = message,
    app_icon = ".\\icon.ico",
    timeout = 6
    )


if __name__ == "__main__":
    while True:
        # notifyMe("Harry", "Lets stop the spread of this virus together")
        myHtmlData = requests.get('https://www.mohfw.gov.in/').text
        soup = BeautifulSoup(myHtmlData, 'html.parser')
        comments = soup.find_all(string=lambda text: isinstance(text, Comment))
        
        myDataStr = ""
        for each in comments:
            if 'tbody' in str(each):
                soup = BeautifulSoup(each, 'html.parser')
        
        for tr in soup.find('tbody').findAll('tr'):
            myDataStr += tr.get_text()
        myDataStr = myDataStr[1:]
        itemList = myDataStr.split("\n\n")
        print(itemList)
    
        states = ['Chandigarh', 'Telengana', 'Uttar Pradesh','Meghalaya']
        for item in itemList[0:22]:
            w=1
            dataList = item.split('\n')
            if dataList[1] in states: 
                nTitle = 'Cases of Covid-19'
                nText = f"State {dataList[1]}\nIndian : {dataList[0]} & Foreign : {dataList[2]}\nCured :  {dataList[3]}\nDeaths :  {dataList[4]}"  #<-- I changed this
            notifyMe(nTitle, nText)
            time.sleep(2)
        time.sleep(3600)

【讨论】:

    猜你喜欢
    • 2016-11-29
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 2023-03-07
    • 1970-01-01
    • 2014-03-21
    相关资源
    最近更新 更多