urllibとBeautifulSoupでスクレイピングするときに調べたこと

スクレイピングをするときに調べたことを中心に使い方をまとめる。
Python3.6でリクエスト部分にurllib、パース部分にBeautifulSoup4を使って行った。
基本的なことはQuick Start — Beautiful Soup 4.4.0 documentationに書いてあるので、まず読め。

準備

Installing Beautiful Soup — Beautiful Soup 4.4.0 documentation

pip install beautifulsoup4

呼び出し方

pipではbeautifulsoup4でインストールするが、importはbs4

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')

パーサーの指定についてはこの記事を参照するといい。

htmlをリクエストするところ

import urllib.error
import urllib.request

def get_html(url):
    try:
        with urllib.request.urlopen(url) as response:
            html = response.read()
    except urllib.error.URLError as e:
        print(e, url)
        html = ''
    return html

単要素の取得はfind()を使う

引数の説明などはfind_all()関数の説明に書いてある。下記のように使える。
返り値は<class 'bs4.element.Tag'>(概要はここ)かNoneになる。

hoge = soup.find(id='hoge')
fuga_text = hoge.find('span', class_='fuga').string

複数要素の取得にはselect()とfind_all()を使う

どちらも返り値は配列。

  • find_all()はキーワードごとに値を指定する形式
  • select()CSS selectorを指定する形式

<div class="hoge fuga">のように複数の値が定義されている場合、find_all(class_='fuga hoge')と指定するとclassの順番が異なるために漏らしてしまう。select('.fuga.hoge')で指定すれば<div class="hoge fuga"><div class="fuga hoge">も両方取得できる。

findは要素が見つからないとNoneを返す

AttributeError: 'NoneType' object has no attribute 'get'とか言われがち。終了させたくない場合は例外書いておく。

try:
    href = soup.find('a.hoge').get('href')
except AttributeError:
    href = ''

その他

  • 呼び出しはtime.sleep(1)つけて毎秒1リクエストにする。
  • 途中で落ちるのが嫌なので、どこまで進んだかログに吐きましょう。