https://docs.python.jp/3/contents.htmlから木構造になっている見出しのうち葉ノードだけを抜き出した
Python学習項目の一覧をつくるために。
成果物
BeautifulSoup.SelectLeafNode.201705150722
前回まで
スクレイピング
木構造の見出し
<div class="toctree-wrapper compound"> <ul> <li class="toctree-l1"><a class="reference internal" href="whatsnew/index.html">What’s New in Python</a><ul> <li class="toctree-l2"><a class="reference internal" href="whatsnew/3.6.html">What’s New In Python 3.6</a><ul> <li class="toctree-l3"><a class="reference internal" href="whatsnew/3.6.html#summary-release-highlights">概要 – リリースハイライト</a></li> <li class="toctree-l3"><a class="reference internal" href="whatsnew/3.6.html#new-features">新しい機能</a><ul> <li class="toctree-l4"><a class="reference internal" href="whatsnew/3.6.html#pep-498-formatted-string-literals">PEP 498: フォーマット済み文字列リテラル</a></li> ...
見出しが木構造になっている。<li>
の中に<ul>
がネストしている。
葉ノードの見出しのみ取り出す
最小構成の見出しをすべて取り出したい。
tree = soup.find('div', class_='toctree-wrapper compound') # 2個目に取得できるものは空だから1個目を取る leafs = tree.select('li:not(:has(ul))')
NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type.
どうやらスクレイピングツールBeautifulSoupはCSSセレクタの擬似クラスをnth-of-type
しか実装してないらしい。not
やhas
などは未実装。
仕方ないので要素を持っているか確認するメソッドを作った。for文がネストするとbreakするとき綺麗なコードが書けないからメソッドにする。
def Has(self, parent, child): for c in parent.children: if child == c.name: return True return False
C#ならスマートに書けたのに。
所感
見出しだけでなく、全体を俯瞰したい。進捗表とか。でも木構造なのでテーブルで一覧できない。どうするか。