85403


# 質問

プログラミング学習本である、コーリー・アルソフ著「独学プログラマー」（2018発行。手元にあるのは2021年発行の刊）のP.243に記載されているウェブスクレイパーのコードを実行するも、エラーが出て原因が特定できません。  
この本のサイトにて補足が公開されていたため、そちらも試しましたがうまくいきません。

<https://shop.nikkeibp.co.jp/front/commodity/0000/C92270/>

pythonを学習している先輩に相談したところ、pythonのバージョンとモジュールの組み合わせが悪いのではないか、ssh通信の認証を回避する必要があるのかも、といった仮説を頂きましたが、自分自身もまだ学習をはじめたてでもあり、うまく理解ができませんでした。  
ちなみにpythonは3.10.0です。

下記にコードとエラーを記載したので、原因が特定できる方がいたら教えていただきたいです。  
よろしくお願い致します。

# コード

[code]

    import urllib.request
    from bs4 import BeautifulSoup
    import ssl
    ssl._create_default_https_context = ssl._create_unverified_context
    
    class Scraper:
        def __init__(self, site):
            self.site = site
    
        def scrape(self):
            r = urllib.request.urlopen(self.site)
            html = r.read()
            parser = "html.parser"
            sp = BeautifulSoup(html, parser)
            print(html)
            for tag in sp.find_all("a"):
                url = tag.get("href")
                print(url)
                if url is None:
                    continue
                if "topics" in url:
                    print("\n" + url)
    
    news = "https://xtrend.nikkei.com/atcl/contents/new/"
    Scraper(news).scrape()
    
    
[/code]

# エラー

[code]

    Traceback (most recent call last):
      File "/Users/taguchimasataka/Desktop/p241のコピー.py", line 26, in <module>
        Scraper(news).scrape()
      File "/Users/taguchimasataka/Desktop/p241のコピー.py", line 15, in scrape
        sp = BeautifulSoup(html, parser)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/__init__.py", line 228, in __init__
        self._feed()
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/__init__.py", line 289, in _feed
        self.builder.feed(self.markup)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/builder/_htmlparser.py", line 215, in feed
        parser.feed(markup)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/html/parser.py", line 110, in feed
        self.goahead(0)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/html/parser.py", line 178, in goahead
        k = self.parse_html_declaration(i)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/html/parser.py", line 269, in parse_html_declaration
        self.handle_decl(rawdata[i+2:gtpos])
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/builder/_htmlparser.py", line 160, in handle_decl
        self.soup.endData(Doctype)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/__init__.py", line 365, in endData
        self.object_was_parsed(o)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/__init__.py", line 370, in object_was_parsed
        previous_element = most_recent_element or self._most_recent_element
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/element.py", line 1054, in __getattr__
        return self.find(tag)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/element.py", line 1292, in find
        l = self.find_all(name, attrs, recursive, text, 1, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/element.py", line 1313, in find_all
        return self._find_all(name, attrs, text, limit, generator, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/element.py", line 528, in _find_all
        strainer = SoupStrainer(name, attrs, text, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/element.py", line 1610, in __init__
        self.text = self._normalize_search_value(text)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/bs4/element.py", line 1615, in _normalize_search_value
        if (isinstance(value, str) or isinstance(value, collections.Callable) or hasattr(value, 'match')
    AttributeError: module 'collections' has no attribute 'Callable'
    
    
[/code]


CC BY-SA 4.0
2021-12-29T13:05:18.287
85399
2021-12-29T18:56:15.973
2021-12-29T16:14:15.120
3060
50697
question
python beautifulsoup
pythonでのウェブスクレイピングにエラーが出るので、原因を特定していただきたいです。


エラーの直接の原因は、 BeautifulSoup4 が内部で Python 標準ライブラリの `collections.Callable`
を参照しているせいです。これは Python 3.10 で削除されました。

現時点の最新版である BeautifulSoup4 4.10.0 では修正済みのようなのでアップデートしてみてください。うまくいかないようなら Python
3.9 以下を使ってください。


CC BY-SA 4.0
2021-12-29T18:56:15.973
85403
2021-12-29T18:56:15.973
2259
85399
answer