素人がPythonでWebスクレイピングを実装する6

よこのじ(@yokonoji_work)です。

素人がPythonでWebスクレイピングを実装する」の第6回です。第5回に引き続きコードを書いていきます。今回はスクレイピングできる形にして、Requestsによる文字化けをBeautiful Soupで回避できることを確認します。

文字化けしないか確認する

早速ですが、こちらがスクレイピングできる形のソースコードです。In [6]の部分でtitleタグの内容を抽出して表示させています。スクレイピング対象は「阿部 寛のホームページ」です。

Requestsによる文字化けは、HTTPヘッダーのContent-Typeに「textタイプが含まれていてcharsetがない」時にエンコーディングがISO-8859-1になるのが原因でした。「阿部 寛のホームページ」でRequestsによる判定r.encordingを確認するとISO-8859-1ですね。そして、ISO-8859-1でデコードされたr.textを使用して抽出したので、日本語のtitleが正しく表示されずに文字化けしています。

 

Content-TypeはGoogle Chromeのアドレスバーにchrome://net-internals/#eventsを入力すると確認できます。

このブログ「よこのじ.work」を例にみてみると、content-typeでutf-8が指定されているのが分かります。「阿部 寛のホームページ」では正しく設定されていないのかcontent-typeがありませんので、エンコーディングがRequestsのデフォルト値であるISO-8859-1となっています。

python-scraping-6-yokonojiutf8

ちなみに、「阿部 寛のホームページ」のmetaタグによるエンコーディングの指定はx-sjisとなっており、これはShift_JISと同じもののようです。

python-scraping-6-abehirosi

次に、ISO-8859-1でデコードされたr.textではなく、デコードされていないr.contentをBeautiful Soupに渡して、Beautiful Soup側でデコードしてtitleを表示させました。

こちらでは正しく「阿部 寛のホームページ」と表示されました。Beautiful Soupで文字化けを回避できることが分かりましたね。

なお、調査中に分かったのですが、Requests側でもr.encoding = r.apparent_encodingとすると、HTMLのバイト列から文字コードを推定してくれるようです。これにはChardetが利用されています。Beautiful Soup側でも同じものを使っていますが、Beautiful Soupはより多くの推定をしているようなのでBeautiful Soupに任せておけば間違いはなさそうです。

こちらがr.apparent_encodingを利用した例です。エンコーディングをSHIFT_JISと特定して文字化けもありませんね。

スクレイピングしてみた

ここまでのコードでは、titleを抽出することができます。その他の要素としてh2タグを抽出したのがこちらの結果になります。対象サイトは「よこのじ.work」です。

ちゃんとh2タグが抽出できているようです。しかし、ヘッダーにある「Web開発、ブロックチェーン、機械学習、心理学の情報発信」やサイドバーの項目名もh2なので一緒に抽出されています。対象を絞ってスクレイピングする方法は知っておきたいですね。

また、他人のサイトに負荷をかけないためにアクセス間隔を制限したり、エクセルやスプレッドシートに記載された複数のURLをスクレイピングの対象としたり、結果をエクセルやスプレッドシートに保存するという実利用を想定した機能も欲しいところです。

さて、第6回はこれで終わりです。たった数行でスクレイピングプログラムができてしまうというのはすごいですね。これをどう活用するかというところも考えていきたいと思います。

 

Webデータの巡回収集と解析をすべて自動で処理しよう

素人がPythonでWebスクレイピングを実装する1
素人がPythonでWebスクレイピングを実装する2
素人がPythonでWebスクレイピングを実装する3
素人がPythonでWebスクレイピングを実装する4
素人がPythonでWebスクレイピングを実装する5
素人がPythonでWebスクレイピングを実装する7
素人がPythonでWebスクレイピングを実装する8