【问题标题】:BeautifulSoup Python NoneType object has no attribute 'text'BeautifulSoup Python NoneType 对象没有属性“文本”
【发布时间】:2021-01-25 02:24:47
【问题描述】:

我正在尝试使用 selenium 和 beautifulsoup 4 抓取一个加载了 javascript 的网站 https://e-consulta.sunat.gob.pe/cl-at-ittipcam/tcS01Alias

但是,当尝试从树中检索元素或子项(子分支)时,我收到此错误

bloquefecha=bloque.find('div[@class="date"]').text

AttributeError: 'NoneType' 对象没有属性 'text'

i'm attaching HERE a snapshot of my code and the developers console for illustrative purposes

这是我的代码:

def beautifulseleniumsunat2():
navegador = webdriver.Chrome()
navegador.get("https://e-consulta.sunat.gob.pe/cl-at-ittipcam/tcS01Alias")
time.sleep(7)  # esperamos 7 segundos a que cargue la pagina
pagsunat = navegador.page_source
soup = BeautifulSoup(pagsunat, "html.parser")
print (soup.prettify())

bloquesdias2 = soup.select('td[class*="table-bordered calendar-day current"]')
listafecha = []
listacompra=[]
listaventa=[]
for bloque in bloquesdias2:
    bloquefecha=bloque.find('div[@class="date"]') #ALSO tried with findall and iterating with FOR loop on each element but ERROR says it's not iterable
    listafecha.append(bloquefecha.text)
    bloquecompra=bloque.find('div[@class="event normal-all-day begin end"]') #ALSO tried with findall and iterating with FOR loop on each element but ERROR says it's not iterable
    listacompra.append(bloquecompra.text)
    bloqueventa = bloque.find('div[@class="event pap-all-day begin end"]') #ALSO tried with findall and iterating with FOR loop on each element but ERROR says it's not iterable
    listaventa.append(bloquecompra.text)

listafinal=[listacompra,listaventa,listafecha]
print (listafinal)

【问题讨论】:

    标签: python selenium beautifulsoup


    【解决方案1】:

    会发生什么?

    正如 Aziz Sonawalla 所述,您必须将类作为分隔参数传递给 find(),但这不会解决您的所有问题。因为如果元素不可用,它将再次引发错误,例如如果没有 compra / ventra 条目。

    如何解决?

    您必须获取错误 - 如果没有错误,try 会给您结果except 会将结果设置为空字符串。

    try:
            bloquecompra = day.select_one('div[class*="normal-all-day"]').get_text().split()[1]
        except:
            bloquecompra = ''
    

    示例

    您可以在打印(soup.prettify())后替换所有代码:

    data = []
    
    for day in soup.select('table.calendar-table.table.table-condensed > tbody td[class*="current"]'):
        bloquefecha = day.select_one('div.date').get_text()
        try:
            bloquecompra = day.select_one('div[class*="normal-all-day"]').get_text().split()[1]
        except:
            bloquecompra = ''
        
        try:
            bloqueventa = day.select_one('div[class*="pap-all-day"]').get_text().split()[1]
        except:
            bloqueventa = ''
        
        data.append(';'.join([bloquefecha,bloquecompra,bloqueventa]))
    data    
    

    输出

    ['1;3.618;3.624',
     '2;;',
     '3;;',
     '4;;',
     '5;3.624;3.628',
     '6;3.627;3.631',
     '7;3.625;3.630',
     '8;3.620;3.623',
     '9;3.610;3.615',
     '10;;',
     '11;;',
     '12;3.615;3.618',
     '13;3.606;3.608',
     '14;3.610;3.615',
     '15;3.610;3.613',
     '16;3.610;3.614',
     '17;;',
     '18;;',
     '19;3.609;3.617',
     '20;3.611;3.615',
     '21;3.612;3.615',
     '22;3.618;3.622',
     '23;;',
     '24;;',
     '25;;',
     '26;;',
     '27;;',
     '28;;',
     '29;;',
     '30;;',
     '31;;']
    

    【讨论】:

    • 非常感谢您的帮助!! .这绝对是我需要的。此外,这种方法将帮助我完成我面临的其他具有挑战性的网络抓取任务。将对您在 soup.select('table.calendar-table.table.table-condensed > tbody td[class*="current"]') 使用的 select 方法进行更多研究#(我不完全理解该表达式中的点和 > 正在评估什么,但会发现)因为它是解决问题的关键。
    • 乐于助人。了解有关css selectors 的更多信息您不必使用它们,但我认为它们更强大、更精确。
    【解决方案2】:

    find() 在找不到您要查找的 div 时返回 None,因此您的代码正在调用 None.text,这就是 Python 抱怨 NoneType 的原因(即 None 对象)没有属性text

    Beautiful Soup documentation,您需要将类作为单独的参数传递给find()

    bloque.find("div", { "class" : "date" }).text
    

    【讨论】:

    • 感谢您的回复。但是我仍然遇到同样的错误AttributeError: 'NoneType' object has no attribute 'text'。我相信这可能与我进行部分类名匹配的行有关:bloquesdias2 = soup.select('td[class*="table-bordered calendar-day current"]') 但是,当我打印 bloquesdias2.text 时,它会提取所有需要的数据,只是它的格式不正确,它正在提取所有来自子标签的批量文本。这就是为什么我试图提取每个孩子的标签文本并将其放在一个列表中,但到目前为止没有成功
    • 如果您收到错误 NoneType has no attribute text for bloquesdias2.text 那么您应该无法打印 bloquesdias2.text。打印语句将失败。您的错误可能来自其他地方。
    猜你喜欢
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    相关资源
    最近更新 更多