!!! サイト改修中のため表示が乱れる場合があります(1月末頃まで) !!!
未分類

28-1. Webサイトのシンプルなスクレイピング

はじめに

シンプルなWebページのスクレイピングを試してみましょう。

対象のWebページ

ポケモンWikiの「ポケモン一覧」ページから全ポケモン名を取得してみます。

ポケモン一覧

実行環境

WinPython3.6をおすすめしています。

WinPython - Browse /WinPython_3.6/3.6.7.0 at SourceForge.net
Portable Scientific Python 2/3 32/64bit Distribution for Windows

Google Colaboratoryが利用可能です。

Google Colab

HTMLソースの取得

必要なパッケージをインストールします。

pip install requests
pip install beautifulsoup4

URLを指定してHTMLソースを取得します。なお、URLに日本語が含まれる場合、コピペすると自動で「URLエンコード」されて「%E3%83%9D・・・」という文字列になるかと思います。そうでない場合、あるいはプログラム中で日本語からURLを生成するような場合には手動でURLエンコードする必要がありますのでご留意ください。

import requests
from bs4 import BeautifulSoup

#URL
url = 'https://wiki.xn--rckteqa2e.com/wiki/%E3%83%9D%E3%82%B1%E3%83%A2%E3%83%B3%E4%B8%80%E8%A6%A7'

#HTML内容を文字列として取得
res = requests.get(url)
soup = BeautifulSoup(res.content, 'html.parser')
html = str(soup)
print('--------- HTML内容 ---------')
print(html[:500])
print('----------------------------')
--------- HTML内容 ---------
<!DOCTYPE html>

<html class="client-nojs" dir="ltr" lang="ja">
<head>
<meta charset="utf-8"/>
<title>ポケモン一覧 - ポケモンWiki</title>
<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>
<script>(window.RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"ポケモン一覧","wgTitle":"ポケモン一覧","wgCurRevisionId":518284,"wgRevisionI
----------------------------

HTMLの冒頭の500文字を表示しました。注意点として、コンソールで改行されている場所には改行コード「/n」が隠れています。

どうやってポケモン名を取得するか

ページを見ると、図鑑番号のそばにポケモン名があります。

HTMLソースを見ると、<td>001/n</td> という文字列が図鑑番号で、title=” の後にポケモン名が来るという法則が分かります。

ポケモン名の取得

長いHTMLソースから特定の文字列を見つける関数を作りました。

#長い文字列から特定の文字列を探して開始インデックスを返す
#検索開始位置とそこからの検索範囲を指定できる
def find_index(html, text, start, length=9999999):
    for i in range(length):
        if html[start+i:start+i+len(text)] == text:
            return i
    return -1 #見つからなければ-1を返す


#図鑑番号(ゼロ埋めして3桁に)
num = str(1).zfill(3)
print(num)

#図鑑番号の位置
text = '<td>' + num + '\n</td>'
index = find_index(html, text, 0)
print(index)
print('--------- HTML内容 ---------')
print(html[index:index+150])
print('----------------------------')
001
6447
--------- HTML内容 ---------
<td>001
</td>
<td><a href="/wiki/%E3%83%95%E3%82%B7%E3%82%AE%E3%83%80%E3%83%8D" title="フシギダネ">フシギダネ</a>
</td>
<td><a href="/wiki/%E3%81%8F%E3%81%95" t
----------------------------

<td>001/n</td> を探すと6447文字目から始まることが分かりました。その場所から150文字を表示してみると、たしかにこの付近で間違いなさそうです。

最後に、その場所から初めて登場する title=”“> の場所を見つけ、間に挟まれたポケモン名を取得します。

#ポケモン名を検出
start = find_index(html, 'title="', index) + len('title="')
end = find_index(html, '">', index)
print(start, end)
name = html[index+start:index+end]
print(name)
87 92
フシギダネ

87文字目から91文字目までの「フシギダネ」が取得できました。

まとめ

ちなみに図鑑番号が001だからといって「001」だけで探そうとすると、長いHTMLソースの中にたまたまあった無関係な001がヒットしてしまうことがあるので、欲しい部分に特有の表現を指定することが大切です。そのためにわざわざ <td>001/n</td> を指定しました。

このような感じでfor文を回せば全ポケモン名を取得できますし、同様に各ポケモンのリンクURLも取得できますので、子ページの内容を取ってくることも可能です。

リアクションのお願い

「参考になった!」「刺激された!」と思ったらぜひリアクションをしましょう。エンジニアの世界はGive and Takeによって成り立っています。これからも無料で良質な情報にアクセスできるよう、Giveする人への感謝をリアクションで示しましょう!

この記事をシェアする

自身のブログ等で使用する場合は引用を忘れずに!

また、寄付も受け付けています。コーヒー1杯でとても喜びます(*˘︶˘*)

 Amazonでギフト券(アマギフ)を贈る

こちらのリンク から金額を指定してお贈りください。(デフォルトで10000円になっているのでご変更ください)

配送:Eメール
受取人:staffあっとvigne-cla.com
贈り主:あなたのお名前やニックネーム
メッセージ:◯◯の記事が参考になりました。など

のようにご入力ください。見返りはありませんのでご了承ください。

 Amazonで食事券(すかいらーく優待券)を贈る

500円 1000円 2000円 5000円 からお贈りください。

配送:Eメール
受取人:staffあっとvigne-cla.com
贈り主:あなたのお名前やニックネーム
メッセージ:◯◯の記事が参考になりました。など

のようにご入力ください。見返りはありませんのでご了承ください。

 その他、ギフト券やクーポン券をメールで贈る

デジタルのギフト券/クーポン券はメールアドレス(staffあっとvigne-cla.com)までお送りください。受領の返信をいたします。
紙のギフト券/クーポン券は 「郵便物はこちらへ」の住所 まで送付してください。名刺やメールアドレスを同封していただければ受領の連絡をいたします。
余った株主優待券等の処理におすすめです。
いずれも見返りはありませんのでご了承ください。

不明点はSNSでお気軽にご連絡ください

ビネクラのTwitter・Youtubeでコメントをください!


Slack・Discordの場合はこちらの公開グループに参加してShoya YasudaまでDMをください!


※当ブログに関することは何でもご相談・ご依頼可能です。

この記事を書いた人
Yasuda

博士(理学)。専門は免疫細胞、数理モデル、シミュレーション。米国、中国で研究に携わった。遺伝的アルゴリズム信者。物価上昇のため半額弁当とともに絶滅寸前。

タイトルとURLをコピーしました