首页 > 解决方案 > BeautifulSoup:使用 .h1.text() 时出现“TypeError:'str' 对象不可调用”

问题描述

编辑 - 这是一个并发的期货问题,而不是 BS4 问题。并发期货在检索数据后返回一个空列表 - 这导致来自 BS4 的 NoneType 错误。

我正在尝试使用 Beautiful Soup 从 URL 列表中抓取 H1,但TypeError: 'str' object is not callable在其中一个 URL 上出现错误。

如果我打印输出,我可以看到我在错误之前检索了 3 个 h1。

如果我删除.h1.text.strip()我会得到一个不同的错误,尽管奇怪的是它打印了 4 次而不是 3 次。

例如,我改为bsh_h1 = bsh.h1.text.strip()运行bsh_h1 = bsh四次并产生错误:TypeError: unhashable type: 'ResultSet'

我试过放置 try / except 块,但它似乎在代码的其他地方产生错误,所以觉得我错过了一些基本的东西。也许 BS4 正在返回 NoneType 我需要跳过它?

这是我的代码。

import concurrent.futures
from bs4 import BeautifulSoup
from urllib.request import urlopen

CONNECTIONS = 1

archive_url_list = [
    "https://web.archive.org/web/20171220015929/http://www.manueldrivingschool.co.uk:80/prices.php",
    "https://web.archive.org/web/20160313085709/http://www.manueldrivingschool.co.uk/lessons_prices.php",
    "https://web.archive.org/web/20171220002420/http://www.manueldrivingschool.co.uk:80/prices",
    "https://web.archive.org/web/20201202094502/https://www.manueldrivingschool.co.uk/success",
]

archive_h1_list = []
def get_archive_h1(h1_url):
    html = urlopen(h1_url)
    bsh = BeautifulSoup(html.read(), 'lxml')
    bsh = bsh.h1.text.strip()
    return bsh.h1.text.strip()

def concurrent_calls():
    with concurrent.futures.ThreadPoolExecutor(max_workers=CONNECTIONS) as executor:
        f1 = executor.map(get_archive_h1, archive_url_list)
        for future in concurrent.futures.as_completed(f1):
            try:
                data = future.result()
                archive_h1_list.append(data)
            except Exception:
                archive_h1_list.append("No Data Received!")
                pass

if __name__ == '__main__':
    concurrent_calls()
    print(archive_h1_list)

PS:我正在使用并发期货进行多线程处理。我最初认为这是问题所在,但我现在倾向于 BS4..

标签: pythonbeautifulsoup

解决方案


您正在从中提取字符串bsh,然后尝试从中访问h1- 由于字符串没有h1方法/属性,这将失败。

bsh = bsh.h1.text.strip()
return bsh.h1.text.strip()

相反,只需执行以下操作:

return bsh.h1.text.strip()

推荐阅读