Webスクレイピング入門にようこそ!

環境構築

Webスクレイピングを行うためにはまず、環境構築が必要です。 今回は selenium を使用していきます。また、画像を扱う上で必要になってくるPillow のインストールの仕方もお伝えします。

Seleniumのインストールと準備

pip3 install selenium もしくは、pip install selenium とターミナル等で入力しインストールしてください。
※Anacondaでインストールしている場合は、python -m pip install selenium の方が安全かもしれません。

動かしてみる(Firefox)

こちらからFirefoxをダウンロードしておきましょう。次にGoogleChromeもお伝えするので、Firefoxでなくても大丈夫です。

まずは、seleniumを使ってみましょう。

In [1]:
# seleniumの読み込み
from selenium import webdriver

# 一時停止用の標準ライブラリの読み込み
from time import sleep

それでは、FirefoxのWebブラウザを立ち上げましょう。

In [2]:
# firefoxを使いますよと宣言
browser = webdriver.Firefox()
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
/usr/local/lib/python3.7/site-packages/selenium/webdriver/common/service.py in start(self)
     75                                             stderr=self.log_file,
---> 76                                             stdin=PIPE)
     77         except TypeError:

/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors, text)
    755                                 errread, errwrite,
--> 756                                 restore_signals, start_new_session)
    757         except:

/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, start_new_session)
   1498                             err_msg += ': ' + repr(err_filename)
-> 1499                     raise child_exception_type(errno_num, err_msg, err_filename)
   1500                 raise child_exception_type(err_msg)

FileNotFoundError: [Errno 2] No such file or directory: 'geckodriver': 'geckodriver'

During handling of the above exception, another exception occurred:

WebDriverException                        Traceback (most recent call last)
<ipython-input-2-af154e14a3fd> in <module>()
      1 # firefoxを使いますよと宣言
----> 2 browser = webdriver.Firefox()

/usr/local/lib/python3.7/site-packages/selenium/webdriver/firefox/webdriver.py in __init__(self, firefox_profile, firefox_binary, timeout, capabilities, proxy, executable_path, options, service_log_path, firefox_options, service_args, desired_capabilities, log_path, keep_alive)
    162                 service_args=service_args,
    163                 log_path=service_log_path)
--> 164             self.service.start()
    165
    166             capabilities.update(options.to_capabilities())

/usr/local/lib/python3.7/site-packages/selenium/webdriver/common/service.py in start(self)
     81                 raise WebDriverException(
     82                     "'%s' executable needs to be in PATH. %s" % (
---> 83                         os.path.basename(self.path), self.start_error_message)
     84                 )
     85             elif err.errno == errno.EACCES:

WebDriverException: Message: 'geckodriver' executable needs to be in PATH.

Message: 'geckodriver' executable needs to be in PATH. というエラーがおそらく出ると思います。
これは geckodriver が入ってませんよというエラーになります。Macの方は下記コマンドでインストールしてください。
Macの方
brew install geckodriver
Windowsの方

Windowsの方は少し面倒ですが、こちらから geckodriver をダウンロード&展開して、そのフォルダの中の geckodriver.exe を作業ファイルと同じ階層に置きましょう。

以下のように作業しているファイルと同じ階層に回答した geckodriver.exe を置いてください。

geckodriver を準備できたところで先程のコードをもう一度実行してみよう。

In [3]:
# Macの方
browser = webdriver.Firefox()

# Windowsの方
browser = webdriver.Firefox('geckodriver.exe')

おそらくFirefoxが立ち上がったのではないでしょうか。このようにたったの一行でWebブラウザを起動することができます。

動かしてみる(Google Chrome)

Chromeも同様に行っていきましょう。 Firefoxのgeckodriverと同様、Google Chromeでは、 chromedriver が必要となります。

Macの方
brew install chromedriver
Windowsの方

まず こちら からChromeDriver.exeをダウンロードします。

先程の用に作業ファイルと同階層に chromedriver.exe を置いてください。

準備ができたのでChromeを起動させてみましょう。

In [10]:
# Google Chromeを使いますよと宣言
# Macの方
browser = webdriver.Chrome()

# Windowsの方
browser = webdriver.Chrome('chromedriver.exe')

Chromeが自動で立ち上がったかと思います。これで準備完了です。

Pillow

画像を扱うためのライブラリである Pillow をインストールしましょう。

pip3 install Pillow

もしくは、

pip install Pillow

でインストールしましょう。

自動でログインしよう

Seleniumの基礎

必要なライブラリのimport

In [1]:
import selenium
In [2]:
from selenium import webdriver

Webブラウザの自動立ち上げ

Google Chromeを開きましょう。

In [5]:
browser = webdriver.Chrome()

起動した browser を用いてhttp://google.com/ にアクセス

In [6]:
browser.get('http://google.com/')

ブラウザを閉じる

In [7]:
browser.quit()

自動でログイン

以下のページのフォームを用いて、自動でログインをしてみましょう。

Webサイトにアクセス

In [8]:
browser = webdriver.Chrome()
In [9]:
browser.get('https://scraping-for-beginner.herokuapp.com/login_page')

フォームの入力

ユーザー名の入力
In [10]:
# 要素(element)を指定
elem_username = browser.find_element_by_id('username')
In [11]:
# 文字を入力
elem_username.send_keys('imanishi')
パスワードの入力
In [13]:
elem_password = browser.find_element_by_id('password')
In [14]:
elem_password.send_keys('kohei')

ボタンのクリック

In [15]:
elem_login_btn = browser.find_element_by_id('login-btn')
In [16]:
elem_login_btn.click()

テキストデータを自動抽出

演習

先程使用した以下のページにアクセスし、ログインするまでの流れを selenium を用いて実装してください。 https://scraping-for-beginner.herokuapp.com/login_page

解答は先ほどのコードを確認してください。

In [49]:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://scraping-for-beginner.herokuapp.com/login_page')
In [50]:
elem_username = browser.find_element_by_id('username')
elem_username.send_keys('imanishi')
In [51]:
elem_password = browser.find_element_by_id('password')
elem_password.send_keys('kohei')
In [52]:
elem_login_btn = browser.find_element_by_id('login-btn')
elem_login_btn.click()

テキストデータの取得

講師名

In [53]:
elem = browser.find_element_by_id('name')
In [54]:
elem.text
Out[54]:
'今西 航平'
In [55]:
name = elem.text
type(name)
Out[55]:
str

所属企業

In [56]:
elem = browser.find_element_by_id('company')
elem.text
Out[56]:
'株式会社キカガク'

生年月日

In [57]:
elem = browser.find_element_by_id('birthday')
elem.text
Out[57]:
'1994年7月15日'

出身

In [58]:
elem = browser.find_element_by_id('come_from')
elem.text
Out[58]:
'千葉県'

趣味

In [59]:
elem = browser.find_element_by_id('hobby')
elem.text
Out[59]:
'バスケットボール\n読書\nガジェット集め'
In [60]:
hobby = elem.text
hobby
Out[60]:
'バスケットボール\n読書\nガジェット集め'
In [61]:
hobby.replace('\n', ',')
Out[61]:
'バスケットボール,読書,ガジェット集め'
In [62]:
hobby.replace('\n', '')
Out[62]:
'バスケットボール読書ガジェット集め'

一括で取得

各項目名

In [63]:
elem_th = browser.find_element_by_tag_name('th')
In [64]:
elem_th.text
Out[64]:
'講師名'
In [65]:
elems_th = browser.find_elements_by_tag_name('th')
In [66]:
elems_th.text
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-66-d98a663d558c> in <module>()
----> 1 elems_th.text

AttributeError: 'list' object has no attribute 'text'
In [67]:
type(elems_th)
Out[67]:
list
In [68]:
elems_th
Out[68]:
[<selenium.webdriver.remote.webelement.WebElement (session="7c7997a25565eb1fbf2a2ca103c51b72", element="0.6800993313991661-6")>,
 <selenium.webdriver.remote.webelement.WebElement (session="7c7997a25565eb1fbf2a2ca103c51b72", element="0.6800993313991661-7")>,
 <selenium.webdriver.remote.webelement.WebElement (session="7c7997a25565eb1fbf2a2ca103c51b72", element="0.6800993313991661-8")>,
 <selenium.webdriver.remote.webelement.WebElement (session="7c7997a25565eb1fbf2a2ca103c51b72", element="0.6800993313991661-9")>,
 <selenium.webdriver.remote.webelement.WebElement (session="7c7997a25565eb1fbf2a2ca103c51b72", element="0.6800993313991661-10")>]
In [69]:
len(elems_th)
Out[69]:
5
In [70]:
elems_th[0].text
Out[70]:
'講師名'
In [71]:
elems_th[1].text
Out[71]:
'所属企業'
In [72]:
keys = []
for elem_th in elems_th:
    key = elem_th.text
    keys.append(key)
In [73]:
keys
Out[73]:
['講師名', '所属企業', '生年月日', '出身', '趣味']

各値

In [74]:
elems_td = browser.find_elements_by_tag_name('td')
In [75]:
values = []
for elem_td in elems_td:
    value = elem_td.text
    values.append(value)
In [76]:
values
Out[76]:
['今西 航平', '株式会社キカガク', '1994年7月15日', '千葉県', 'バスケットボール\n読書\nガジェット集め']

CSVファイルに出力

In [77]:
import pandas as pd
In [78]:
#空のDataFrameを定義
df = pd.DataFrame()
In [79]:
df['項目'] = keys
df['値'] = values
In [80]:
df
Out[80]:
項目
0 講師名 今西 航平
1 所属企業 株式会社キカガク
2 生年月日 1994年7月15日
3 出身 千葉県
4 趣味 バスケットボール\n読書\nガジェット集め
In [81]:
df.to_csv('講師情報.csv')
In [82]:
df.to_csv('講師情報.csv', index=False)

ランキング形式のサイトからまとめて情報収集

以下のページにある観光地ランキングの情報を取得します。

1つの観光地の情報を取得

ページにアクセス

In [1]:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://scraping-for-beginner.herokuapp.com/ranking/')

観光地名の取得

In [2]:
elem_rankingBox = browser.find_element_by_class_name('u_areaListRankingBox')
In [5]:
elem_title = elem_rankingBox.find_element_by_class_name('u_title')
elem_title.text
Out[5]:
'1\n観光地 1'
In [6]:
title = elem_title.text
title
Out[6]:
'1\n観光地 1'
In [7]:
title.split('\n')
Out[7]:
['1', '観光地 1']
In [8]:
title.split('\n')[1]
Out[8]:
'観光地 1'

総合評価の取得

In [12]:
elem_rank = browser.find_element_by_class_name('u_rankBox')
elem_rank = elem_rank.find_element_by_class_name('evaluateNumber')
In [14]:
elem_rank.text
Out[14]:
'4.7'

各項目の評価を取得

楽しさ
In [15]:
elem = browser.find_element_by_class_name('u_categoryTipsItem')
In [18]:
elem = elem.find_element_by_class_name('is_rank')
elem = elem.find_element_by_class_name('evaluateNumber')
In [19]:
elem.text
Out[19]:
'4.6'
人混みの多さ
In [21]:
elem = browser.find_element_by_class_name('u_categoryTipsItem')
In [22]:
elem = elem.find_elements_by_class_name('is_rank')[1]
elem = elem.find_element_by_class_name('evaluateNumber')
In [23]:
elem.text
Out[23]:
'4.5'
景色
In [24]:
elem = browser.find_element_by_class_name('u_categoryTipsItem')
In [25]:
elem = elem.find_elements_by_class_name('is_rank')[2]
elem = elem.find_element_by_class_name('evaluateNumber')
In [26]:
elem.text
Out[26]:
'4.9'
アクセス
In [27]:
elem = browser.find_element_by_class_name('u_categoryTipsItem')
In [28]:
elem = elem.find_elements_by_class_name('is_rank')[3]
elem = elem.find_element_by_class_name('evaluateNumber')
In [29]:
elem.text
Out[29]:
'4.2'

すべての観光地の情報を取得

In [30]:
elem_rankingBox = browser.find_element_by_class_name('u_areaListRankingBox')
In [32]:
elem_title = elem_rankingBox.find_element_by_class_name('u_title')
elem_title.text.split('\n')[1]
Out[32]:
'観光地 1'

観光地名

In [33]:
elem_rankingBox = browser.find_element_by_class_name('u_areaListRankingBox')
elem_title = elem_rankingBox.find_element_by_class_name('u_title')
title = elem_title.text.split('\n')[1]
title
Out[33]:
'観光地 1'
In [34]:
#elements にする
elems_rankingBox = browser.find_elements_by_class_name('u_areaListRankingBox')
In [35]:
len(elems_rankingBox)
Out[35]:
10
In [ ]:
elems_rankingBox = browser.find_elements_by_class_name('u_areaListRankingBox')
In [37]:
titles = []
for elem_rankingBox in elems_rankingBox:
    elem_title = elem_rankingBox.find_element_by_class_name('u_title')
    title = elem_title.text.split('\n')[1]
    titles.append(title)
In [38]:
titles
Out[38]:
['観光地 1',
 '観光地 2',
 '観光地 3',
 '観光地 4',
 '観光地 5',
 '観光地 6',
 '観光地 7',
 '観光地 8',
 '観光地 9',
 '観光地 10']

総合評価

In [42]:
elem_rank = browser.find_element_by_class_name('u_rankBox')
elem_rank = elem_rank.find_element_by_class_name('evaluateNumber')
rank = elem_rank.text
rank
Out[42]:
'4.7'
In [45]:
type(rank)
Out[45]:
str
In [47]:
rank = float(elem_rank.text)
rank
Out[47]:
4.7
In [43]:
elems_rank = browser.find_elements_by_class_name('u_rankBox')
In [44]:
len(elems_rank)
Out[44]:
10
In [48]:
ranks = []
for elem_rank in elems_rank:
    elem_rank = elem_rank.find_element_by_class_name('evaluateNumber')
    rank = float(elem_rank.text)
    ranks.append(rank)
In [49]:
ranks
Out[49]:
[4.7, 4.7, 4.6, 4.5, 4.5, 4.4, 4.3, 4.3, 4.2, 4.1]

各項目

In [51]:
elem = browser.find_element_by_class_name('u_categoryTipsItem')
In [52]:
elem = elem.find_element_by_class_name('is_rank')
elem = elem.find_element_by_class_name('evaluateNumber')
elem.text
Out[52]:
'4.6'
In [53]:
elems = browser.find_elements_by_class_name('u_categoryTipsItem')
In [54]:
categories = []

for elem in elems:
        items = []
        elems_rank = elem.find_elements_by_class_name('is_rank')
        for elem_rank in elems_rank:
            rank = elem_rank.find_element_by_class_name('evaluateNumber').text
            items.append(rank)
        categories.append(items)
In [55]:
categories
Out[55]:
[['4.6', '4.5', '4.9', '4.2'],
 ['4.6', '4.5', '4.9', '4.2'],
 ['4.5', '4.4', '4.8', '4.1'],
 ['4.4', '4.4', '4.8', '4.0'],
 ['4.4', '4.3', '4.7', '4.0'],
 ['4.3', '4.3', '4.7', '3.9'],
 ['4.2', '4.2', '4.6', '3.8'],
 ['4.2', '4.2', '4.6', '3.8'],
 ['4.1', '4.1', '4.5', '3.7'],
 ['4.0', '4.1', '4.4', '3.6']]

Pandasの形式に変換

In [56]:
import pandas as pd
In [60]:
df = pd.DataFrame()
In [61]:
df['観光地名'] = titles
df['総合評価'] = ranks
In [62]:
df
Out[62]:
観光地名 総合評価
0 観光地 1 4.7
1 観光地 2 4.7
2 観光地 3 4.6
3 観光地 4 4.5
4 観光地 5 4.5
5 観光地 6 4.4
6 観光地 7 4.3
7 観光地 8 4.3
8 観光地 9 4.2
9 観光地 10 4.1
In [63]:
df_categories = pd.DataFrame(categories)
df_categories
Out[63]:
0 1 2 3
0 4.6 4.5 4.9 4.2
1 4.6 4.5 4.9 4.2
2 4.5 4.4 4.8 4.1
3 4.4 4.4 4.8 4.0
4 4.4 4.3 4.7 4.0
5 4.3 4.3 4.7 3.9
6 4.2 4.2 4.6 3.8
7 4.2 4.2 4.6 3.8
8 4.1 4.1 4.5 3.7
9 4.0 4.1 4.4 3.6
In [64]:
df_categories.columns = ['楽しさ', '人混みの多さ', '景色', 'アクセス']
df_categories
Out[64]:
楽しさ 人混みの多さ 景色 アクセス
0 4.6 4.5 4.9 4.2
1 4.6 4.5 4.9 4.2
2 4.5 4.4 4.8 4.1
3 4.4 4.4 4.8 4.0
4 4.4 4.3 4.7 4.0
5 4.3 4.3 4.7 3.9
6 4.2 4.2 4.6 3.8
7 4.2 4.2 4.6 3.8
8 4.1 4.1 4.5 3.7
9 4.0 4.1 4.4 3.6
In [65]:
df = pd.concat([df, df_categories], axis=1)
In [66]:
df
Out[66]:
観光地名 総合評価 楽しさ 人混みの多さ 景色 アクセス
0 観光地 1 4.7 4.6 4.5 4.9 4.2
1 観光地 2 4.7 4.6 4.5 4.9 4.2
2 観光地 3 4.6 4.5 4.4 4.8 4.1
3 観光地 4 4.5 4.4 4.4 4.8 4.0
4 観光地 5 4.5 4.4 4.3 4.7 4.0
5 観光地 6 4.4 4.3 4.3 4.7 3.9
6 観光地 7 4.3 4.2 4.2 4.6 3.8
7 観光地 8 4.3 4.2 4.2 4.6 3.8
8 観光地 9 4.2 4.1 4.1 4.5 3.7
9 観光地 10 4.1 4.0 4.1 4.4 3.6
In [67]:
df.to_csv('観光地情報.csv', index=False)

全ページの情報を取得

In [69]:
pagination = browser.find_element_by_id('pagination')
In [72]:
page1 = pagination.find_elements_by_tag_name('li')[1]
In [73]:
page1.find_element_by_tag_name('a').click()
In [ ]:

In [74]:
titles = []
ranks = []
categories = []

browser = webdriver.Chrome()

for page in range(1,4):

    browser.get('https://scraping-for-beginner.herokuapp.com/ranking/?page={}'.format(page))

    # 観光地名
    elems_rankingBox = browser.find_elements_by_class_name('u_areaListRankingBox')
    for elem_rankingBox in elems_rankingBox:
        elem_title = elem_rankingBox.find_element_by_class_name('u_title')
        title = elem_title.text.split('\n')[1]
        titles.append(title)

    # 総合評価
    elems_rank = browser.find_elements_by_class_name('u_rankBox')
    for elem_rank in elems_rank:
        elem_rank = elem_rank.find_element_by_class_name('evaluateNumber')
        rank = float(elem_rank.text)
        ranks.append(rank)

    # 各項目
    elems = browser.find_elements_by_class_name('u_categoryTipsItem')
    for elem in elems:
            items = []
            elems_rank = elem.find_elements_by_class_name('is_rank')
            for elem_rank in elems_rank:
                rank = elem_rank.find_element_by_class_name('evaluateNumber').text
                items.append(rank)
            categories.append(items)
In [75]:
titles
Out[75]:
['観光地 1',
 '観光地 2',
 '観光地 3',
 '観光地 4',
 '観光地 5',
 '観光地 6',
 '観光地 7',
 '観光地 8',
 '観光地 9',
 '観光地 10',
 '観光地 11',
 '観光地 12',
 '観光地 13',
 '観光地 14',
 '観光地 15',
 '観光地 16',
 '観光地 17',
 '観光地 18',
 '観光地 19',
 '観光地 20',
 '観光地 21',
 '観光地 22',
 '観光地 23',
 '観光地 24',
 '観光地 25',
 '観光地 26',
 '観光地 27',
 '観光地 28',
 '観光地 29',
 '観光地 30']
In [76]:
ranks
Out[76]:
[4.7,
 4.7,
 4.6,
 4.5,
 4.5,
 4.4,
 4.3,
 4.3,
 4.2,
 4.1,
 4.1,
 4.0,
 3.9,
 3.9,
 3.8,
 3.7,
 3.7,
 3.6,
 3.5,
 3.5,
 3.4,
 3.3,
 3.3,
 3.2,
 3.1,
 3.1,
 3.0,
 2.9,
 2.9,
 2.8]
In [77]:
categories
Out[77]:
[['4.6', '4.5', '4.9', '4.2'],
 ['4.6', '4.5', '4.9', '4.2'],
 ['4.5', '4.4', '4.8', '4.1'],
 ['4.4', '4.4', '4.8', '4.0'],
 ['4.4', '4.3', '4.7', '4.0'],
 ['4.3', '4.3', '4.7', '3.9'],
 ['4.2', '4.2', '4.6', '3.8'],
 ['4.2', '4.2', '4.6', '3.8'],
 ['4.1', '4.1', '4.5', '3.7'],
 ['4.0', '4.1', '4.4', '3.6'],
 ['4.0', '4.0', '4.4', '3.6'],
 ['3.9', '4.0', '4.3', '3.5'],
 ['3.8', '3.9', '4.3', '3.4'],
 ['3.8', '3.9', '4.2', '3.4'],
 ['3.7', '3.8', '4.2', '3.3'],
 ['3.6', '3.8', '4.1', '3.2'],
 ['3.6', '3.7', '4.1', '3.2'],
 ['3.5', '3.7', '4.0', '3.1'],
 ['3.4', '3.6', '3.9', '3.0'],
 ['3.4', '3.6', '3.9', '3.0'],
 ['3.3', '3.5', '3.8', '2.9'],
 ['3.2', '3.5', '3.8', '2.8'],
 ['3.2', '3.4', '3.7', '2.8'],
 ['3.1', '3.4', '3.7', '2.7'],
 ['3.0', '3.3', '3.6', '2.6'],
 ['3.0', '3.3', '3.6', '2.6'],
 ['2.9', '3.2', '3.5', '2.5'],
 ['2.8', '3.2', '3.4', '2.4'],
 ['2.8', '3.1', '3.4', '2.4'],
 ['2.7', '3.1', '3.3', '2.3']]
In [78]:
df = pd.DataFrame()
In [79]:
df['観光地名'] = titles
df['総合評価'] = ranks
In [80]:
df_categories = pd.DataFrame(categories)
df_categories
Out[80]:
0 1 2 3
0 4.6 4.5 4.9 4.2
1 4.6 4.5 4.9 4.2
2 4.5 4.4 4.8 4.1
3 4.4 4.4 4.8 4.0
4 4.4 4.3 4.7 4.0
5 4.3 4.3 4.7 3.9
6 4.2 4.2 4.6 3.8
7 4.2 4.2 4.6 3.8
8 4.1 4.1 4.5 3.7
9 4.0 4.1 4.4 3.6
10 4.0 4.0 4.4 3.6
11 3.9 4.0 4.3 3.5
12 3.8 3.9 4.3 3.4
13 3.8 3.9 4.2 3.4
14 3.7 3.8 4.2 3.3
15 3.6 3.8 4.1 3.2
16 3.6 3.7 4.1 3.2
17 3.5 3.7 4.0 3.1
18 3.4 3.6 3.9 3.0
19 3.4 3.6 3.9 3.0
20 3.3 3.5 3.8 2.9
21 3.2 3.5 3.8 2.8
22 3.2 3.4 3.7 2.8
23 3.1 3.4 3.7 2.7
24 3.0 3.3 3.6 2.6
25 3.0 3.3 3.6 2.6
26 2.9 3.2 3.5 2.5
27 2.8 3.2 3.4 2.4
28 2.8 3.1 3.4 2.4
29 2.7 3.1 3.3 2.3
In [81]:
df_categories.columns = ['楽しさ', '人混みの多さ', '景色', 'アクセス']
df_categories
Out[81]:
楽しさ 人混みの多さ 景色 アクセス
0 4.6 4.5 4.9 4.2
1 4.6 4.5 4.9 4.2
2 4.5 4.4 4.8 4.1
3 4.4 4.4 4.8 4.0
4 4.4 4.3 4.7 4.0
5 4.3 4.3 4.7 3.9
6 4.2 4.2 4.6 3.8
7 4.2 4.2 4.6 3.8
8 4.1 4.1 4.5 3.7
9 4.0 4.1 4.4 3.6
10 4.0 4.0 4.4 3.6
11 3.9 4.0 4.3 3.5
12 3.8 3.9 4.3 3.4
13 3.8 3.9 4.2 3.4
14 3.7 3.8 4.2 3.3
15 3.6 3.8 4.1 3.2
16 3.6 3.7 4.1 3.2
17 3.5 3.7 4.0 3.1
18 3.4 3.6 3.9 3.0
19 3.4 3.6 3.9 3.0
20 3.3 3.5 3.8 2.9
21 3.2 3.5 3.8 2.8
22 3.2 3.4 3.7 2.8
23 3.1 3.4 3.7 2.7
24 3.0 3.3 3.6 2.6
25 3.0 3.3 3.6 2.6
26 2.9 3.2 3.5 2.5
27 2.8 3.2 3.4 2.4
28 2.8 3.1 3.4 2.4
29 2.7 3.1 3.3 2.3
In [82]:
df = pd.concat([df, df_categories], axis=1)
In [83]:
df
Out[83]:
観光地名 総合評価 楽しさ 人混みの多さ 景色 アクセス
0 観光地 1 4.7 4.6 4.5 4.9 4.2
1 観光地 2 4.7 4.6 4.5 4.9 4.2
2 観光地 3 4.6 4.5 4.4 4.8 4.1
3 観光地 4 4.5 4.4 4.4 4.8 4.0
4 観光地 5 4.5 4.4 4.3 4.7 4.0
5 観光地 6 4.4 4.3 4.3 4.7 3.9
6 観光地 7 4.3 4.2 4.2 4.6 3.8
7 観光地 8 4.3 4.2 4.2 4.6 3.8
8 観光地 9 4.2 4.1 4.1 4.5 3.7
9 観光地 10 4.1 4.0 4.1 4.4 3.6
10 観光地 11 4.1 4.0 4.0 4.4 3.6
11 観光地 12 4.0 3.9 4.0 4.3 3.5
12 観光地 13 3.9 3.8 3.9 4.3 3.4
13 観光地 14 3.9 3.8 3.9 4.2 3.4
14 観光地 15 3.8 3.7 3.8 4.2 3.3
15 観光地 16 3.7 3.6 3.8 4.1 3.2
16 観光地 17 3.7 3.6 3.7 4.1 3.2
17 観光地 18 3.6 3.5 3.7 4.0 3.1
18 観光地 19 3.5 3.4 3.6 3.9 3.0
19 観光地 20 3.5 3.4 3.6 3.9 3.0
20 観光地 21 3.4 3.3 3.5 3.8 2.9
21 観光地 22 3.3 3.2 3.5 3.8 2.8
22 観光地 23 3.3 3.2 3.4 3.7 2.8
23 観光地 24 3.2 3.1 3.4 3.7 2.7
24 観光地 25 3.1 3.0 3.3 3.6 2.6
25 観光地 26 3.1 3.0 3.3 3.6 2.6
26 観光地 27 3.0 2.9 3.2 3.5 2.5
27 観光地 28 2.9 2.8 3.2 3.4 2.4
28 観光地 29 2.9 2.8 3.1 3.4 2.4
29 観光地 30 2.8 2.7 3.1 3.3 2.3

画像の収集

Pillowの使い方

画像の読み込み

こちらの画像をPillowを使って読み込んでみましょう。 image0

In [3]:
from PIL import Image
In [6]:
img = Image.open('sample.JPG')
img
Out[6]:
_images/src_4_4_0.png
In [7]:
img.size
Out[7]:
(1200, 798)

リサイズ

In [8]:
img = img.resize((1024, 768))
In [9]:
img.size
Out[9]:
(1024, 768)

保存

In [10]:
img.save('sample_resize.jpg')

1枚の画像を取得

以下のサイトにアクセスし、1枚目の画像を取得してみましょう。
In [11]:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://scraping-for-beginner.herokuapp.com/image')

要素の取得

In [13]:
elem = browser.find_element_by_class_name('material-placeholder')
elem = elem.find_element_by_tag_name('img')

画像URLの取得

In [24]:
url = elem.get_attribute('src')
url
Out[24]:
'https://scraping-for-beginner.herokuapp.com/static/assets/img/img1.JPG'

画像の取得

In [28]:
import io
from urllib import request
In [29]:
f = io.BytesIO(request.urlopen(url).read())
In [30]:
f
Out[30]:
<_io.BytesIO at 0x10c173b48>
In [31]:
img = Image.open(f)
img
Out[31]:
_images/src_4_21_0.png

画像の保存

In [32]:
img.save('img01.jpg')

すべての画像を収集

1枚の画像取得の流れ

In [33]:
elem = browser.find_element_by_class_name('material-placeholder')
elem = elem.find_element_by_tag_name('img')

url = elem.get_attribute('src')

f = io.BytesIO(request.urlopen(url).read())
img = Image.open(f)
img.save('img01.jpg')
In [34]:
#elementsにする
elems = browser.find_elements_by_class_name('material-placeholder')

# インデックス(要素番号)も取得
for index, elem in enumerate(elems):
    elem = elem.find_element_by_tag_name('img')
    url = elem.get_attribute('src')

    f = io.BytesIO(request.urlopen(url).read())
    img = Image.open(f)
    img.save('image/img{}.jpg'.format(index))

Yahoo!路線情報で検索

池袋駅 から 神田駅 までの路線情報を検索してみましょう。

In [2]:
from_st = '池袋'
to_st = '神田'
url = 'https://transit.yahoo.co.jp/search/result?flatlon=&from={}&tlatlon=&to={}&viacode=&via=&viacode=&via=&viacode=&via=&y=2018&m=10&d=21&hh=15&m2=4&m1=4&type=1&ticket=ic&expkind=1&ws=3&s=0&al=1&shin=1&ex=1&hb=1&lb=1&sr=1&kw=%E7%A5%9E%E7%94%B0'.format(from_st, to_st)
In [3]:
url
Out[3]:
'https://transit.yahoo.co.jp/search/result?flatlon=&from=池袋&tlatlon=&to=神田&viacode=&via=&viacode=&via=&viacode=&via=&y=2018&m=10&d=21&hh=15&m2=4&m1=4&type=1&ticket=ic&expkind=1&ws=3&s=0&al=1&shin=1&ex=1&hb=1&lb=1&sr=1&kw=%E7%A5%9E%E7%94%B0'
In [4]:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get(url)