質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.49%

スクレイピングで要素取得ができない

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 792

TOMO6181

score 30

現在、Pythonを使ったスクレイピングで商品サイトの画像情報を取得しようとしています。
その前段階の処理として、商品画像ページへのリンクを取得しようとしており、以下のコードを作成しました。

import requests as req
from bs4 import BeautifulSoup
import time
import lxml
from selenium import webdriver

def get_requests(url):
    time.sleep(5)
    res = req.get(url)
    return res

if __name__ == '__main__':
    # URL取得
    url = 'https://www.fujiya-peko.co.jp/sweets/products_list/index.html'

    # サイトに接続
    res = get_requests(url)

    # ここからseleniumでボタンを押す
    driver_path = 'C:\pythonCode\chromedriver_win32\chromedriver.exe'
    driver = webdriver.Chrome(driver_path)
    driver.get(url)
    selmoreBtn = driver.find_element_by_class_name('moreInfoBtn')
    selAtag = selmoreBtn.find_element_by_tag_name('a')
    selAtag.click()

    # 以下のクラスで、商品情報一覧を取得
    # flexElement4 boxLink01 jsonBoxLink moreInfoBlock
    soup = BeautifulSoup(res.text, 'lxml')

    productinfo = soup.find('div', class_='moreInfoBlock')

    print(productinfo['class'])
    print(productinfo.string)
    print(productinfo.text)

    divs = productinfo.find_all('div')

    print(len(divs))

    # 商品画像ページへのリンク(aタグのhref属性)を出力
    for div1 in divs:
        adata = div1.find('a')

        if adata is not None:
            print(adata['href'])

対象のサイトには「もっと見る」ボタンがあるため、seleniumを使用して、ボタンをクリックしたときの操作を行うようにしています。
その後で、Beautifulsoupを使用し、HTMLの情報を取得しているのですが、何故か
「productinfo = soup.find('div', class_='moreInfoBlock')」の直後のprint文で「productinfo.string」、「productinfo.text」の
出力結果がNoneになり、その後のdivsの中身も空になってしまっています。

コード上のどこに問題があるか、分かる方がおられましたら宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • meg_

    2019/07/28 21:06 編集

    soup = BeautifulSoup(res.text, 'lxml')

    上記で取得した「soup」には取得したい要素が入っていますか?「もっと見る」ボタンクリック直後は未だ画像が表示されていないかもしれません。

    【追記】
    BeautifulSoupでの(動的なページの)取得は難しいと思いますので、Seleniumで要素を取得するのが良いと思います。

    キャンセル

  • TOMO6181

    2019/07/29 23:59

    ご回答ありがとうございます。
    res.textをprintしてみたところ、moreInfoBlock要素の子要素が
    <figure class="loading"><img src="/assets/img/loaging.gif" alt=""></figure>
    となっており、画像情報の部分がまだできていないようでした。
    ただ、
    res = get_requests(url)

    soup = BeautifulSoup(res.text, 'lxml')
    の直前に持っていっても、time.sleepを入れても、同様にして
    <figure class="loading">
    が表示されて画像部が取得できない状態です。

    キャンセル

回答 2

checkベストアンサー

0

JSON読み出しサンプル
https://requests-docs-ja.readthedocs.io/en/latest/user/quickstart/#json

import requests

r = requests.get("https://www.fujiya-peko.co.jp/sweets/json/sweets.json")

data = r.json()

for i in data:
    print(i["title"], i["image"])

画像保存サンプル

def download_img(url, file_name):

    r = requests.get(url, stream=True)

    if r.status_code == 200:
        with open(file_name, 'wb') as fw:
            fw.write(r.content)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/31 00:07

    具体的なサンプルコートまで頂きありがとうございます。
    JSONの読み出しと、画像保存サンプルにより、画像保存を行うことができました。

    キャンセル

0

画像ページのリンク情報を取得したいが目的だと思いますので、ここのJson情報読み取れば良いと思います。
BeautifulSoup や Selenium なしで取得できるはずです。
商品情報は後から取得しているので、Seleniumで取得する必要があるのは、質問に書いてくださっているものと同意です。

取得すると良いJson情報

https://www.fujiya-peko.co.jp/sweets/json/sweets.json

どう読み解いたか

  1. 全てを表示するボタンがある。Classは、showAllBtn
  2. JSを読み解くとshowAllBtnをクリックした時に、Ajaxで取得しているURLがsweets.json

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/30 00:06

    ご回答ありがとうございます。
    JSを読み解いて、商品情報を記載したJsonファイルを取得する方法もあるのですね。

    前提が漏れていて申し訳ないですが、今最終的にやろうとしていることは、商品情報から画像ファイルを取得することです。その際に、1個1個の画像を右クリック→保存とやっていては時間が膨大にかかるため、それらの作業を自動化させる必要があります。
    繰り返し質問になり重ね重ね申し訳ないですが、JSONファイルをスクレイピングで読み取り、画像ファイルを保存、ということはできますでしょうか?

    キャンセル

  • 2019/07/30 00:22

    `requests`モジュールを使って画像を取得し、`open()`・`with`によるファイル書き込みを行えば、良いと思います。

    前述で述べた画像のURLさえわかっていれば、問題なく保存までできると思います。

    キャンセル

  • 2019/07/31 00:06

    ありがとうございます。
    仰る通り、画像のURLにより画像を保存することができました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる