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

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

新規登録して質問してみよう
ただいま回答率
85.37%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

PyCharm

エディター・開発ツール

Q&A

解決済

1回答

947閲覧

Djangoでseleniumを使ってスクレイピングした複数のデータをリストにいれて表示させることができない。

sakanaku

総合スコア17

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

PyCharm

エディター・開発ツール

0グッド

0クリップ

投稿2020/08/20 16:12

前提・実現したいこと

こんにちわ。Python初学者です。
Djangoを使って動的なwebサイトからスクレイピングしたデータをここでお力を借りてローカルホストに表示さすことができたのですが、2つの部分(<a>タグと<span>タグの部分)をスクレイピングしたデータをfor文で回してすべてのデータを取得したいのですがうまくいきません。

発生している問題

下記のcoll/views.pyのget_date()の関数で、<a>タグを取得して、get()関数で<span>タグの中身を取得したいのですが、どちらか一つの関数しか機能していないような感じになってしまいます。こちらは2つの関数が別々の要素をスクレイピング取得しようとしているから一つの関数しか機能しないんでしょうか??

実現したいこととしましては、指定したwebサイトの<a>タグと<span>タグをすべて取得してできれば、空のリストを作ってスクレイピングしたデータを格納したいのですが、どのようなコードを書けば良いでしょうか?
できればget_date()だけで<a>タグと<span>タグどちらも取得したいです。
ぜひ、ご教授いただけないでしょうか??よろしくお願いします。

該当のソースコード

coll/views.py

from django.shortcuts import render from selenium import webdriver import chromedriver_binary from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options import time import urllib.request options = Options() options.headless = True options.add_argument('--headless') driver = webdriver.Chrome(options=options) driver.get("動的なwebサイトURL") def get_date(requests): selector = '<a>タグの要素' element = driver.find_elements_by_css_selector(selector) element = [a.get_attribute("href") for a in element] context = {'links': element} return render(requests, 'coll/index.html', context) def get(requests): date_element = "<span>の要素" date = driver.find_elements_by_css_selector(date_element) context = {'dates': date} return render(requests, 'coll/index.html', context)

該当のソースコード

templates/coll/index.html

<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> {% for link in links %} {{ link }} {% endfor %} {% for datess in dates %} {{ datess }} {% endfor %} </body>

試したこと

views.pyにget_date()かget()をどちらか一つだけ書いた場合(index.htmlの中身はそれによって少し変数名とかは変えています。)はどちらも正常にローカルホストに表示されます。一つ一つの関数なら欲しいデータの取得することはできていそうです。

本当はget_date()の中だけで<a><span>タグを取得するコードを書きたいので下記のようにしてみたけど<a>タグのデータしか取得できませんでした。こちらどのように改善すれば良いでしょうか?

def get_date(requests): selector = '<a>タグの要素' element = driver.find_elements_by_css_selector(selector) element = [a.get_attribute("href") for a in element] context = {'links': element} date_element = "<span>の要素" date = driver.find_elements_by_css_selector(date_element) conte = {'datess': date} return render(requests, 'coll/index.html', context, conte)

補足情報(FW/ツールのバージョンなど)

mac10.15.3
python3.8

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Python

1def get_date(requests): 2 selector = '<a>タグの要素' 3 element = driver.find_elements_by_css_selector(selector) 4 element = [a.get_attribute("href") for a in element] 5 6 date_element = "<span>の要素" 7 date = driver.find_elements_by_css_selector(date_element) 8 9 context = {'datess': date, 'links': element} 10 return render(requests, 'coll/index.html', context) 11```のように、`context`に1回で渡す

投稿2020/08/20 20:58

編集2020/08/20 20:58
ForestSeo

総合スコア2722

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sakanaku

2020/08/21 06:06

ご回答ありがとうございます。上記のコードを記載するとどちらも取得できました。いつもありがとうございます。スクレイピング結果を少し綺麗に見せたくてリストに格納してみたいのですが、 def get_date(requests): x = [] z = [] selector = '<a>タグの要素' element = driver.find_elements_by_css_selector(selector) element = [a.get_attribute("href") for a in element] date_element = "<span>の要素" date = driver.find_elements_by_css_selector(date_element) の関数で、 このx = [ ]とz = [ ]の中に x.append(a), z.append(date)のようにリストに入れたいのですがどのようなコード表記にしたらうまくいくのでしょうか?また、空のリストを2つ作る意味はないのでしょうか??すいません、ぜひ教えていただきたいです。
ForestSeo

2020/08/21 06:10 編集

element = [a.get_attribute("href") for a in element] で、リストになってませんか? element = [a.get_attribute("href") for a in element] というのは、 ⠀ lst = [] for a in element: ⠀⠀⠀⠀lst.append(a.get_attribute("href")) element = lst を短縮したものです。リスト内包表記です。
sakanaku

2020/08/21 06:12

def get_date(requests): x = [] z = [] selector = '<a>タグの要素' element = driver.find_elements_by_css_selector(selector) element = [a.get_attribute("href") for a in element] x.append(element) date_element = "<span>の要素" dates = driver.find_elements_by_css_selector(date_element) z.append(dates) context = {'links': element, 'dates': dates} return render(requests, 'coll/index.html', context) こんな感じのコードかな?と思ったのですが、出力結果は微動だに変わりません、、、、
sakanaku

2020/08/21 06:13

すいません、コメントが入れ違いになりました。今から試させてもらいます。
sakanaku

2020/08/21 06:26

リスト内包表記とはそういうことなんですね。 date_element = "<span>の要素" こちらのコードもリスト内包表記したくて dates = [driver.find_elements_by_css_selector(date_element)] このようにすると<span>の要素"の出力結果が何も表示されなくなってしまうのですがなぜでしょうか??そしてindex.htmlの方で{{ datess.text }}でもともとは出力されていたので.textをはずして {{ datess }} で出力すると <selenium.webdriver.remote.webelement.WebElement (session="3567e058d791d294439", element="1365c089-3r4d-f2")>, このような奴が表示されてしまいます。 ちなみに<span>タグの中身は日付とキー?のような数字の文字列が入っています。
ForestSeo

2020/08/21 07:36

dates = [datess.text for datess in driver.find_elements_by_css_selector(date_element)] でいいのではないでしょうか?
ForestSeo

2020/08/21 07:37 編集

ちなみに、 内包表記はhttps://note.nkmk.me/python-list-comprehension/が詳しいです。
sakanaku

2020/08/21 07:55

内包表記のURLまでありがとうございます。 はい、このようにしてもうまくいきません dates = [datess.text for datess in driver.find_elements_by_css_selector(date_element)] が、いただいた参考URLでいろいろ勉強してみます。 いつも、ありがとうございます。
ForestSeo

2020/08/21 09:39

> このようにしてもうまくいきません テンプレートでdatesをforで回しても表示できませんか?
sakanaku

2020/08/21 15:15

<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> {% for link in links %} {{ link }} {% endfor %} <p>--------------------------------------------</p>> {% for datess in dates %} {{ datess }} {% endfor %} </body> はいこのような、コードでしていますが <selenium.webdriver.remote.webelement.WebElement (session="fgsfggv111b4", element="kkkc133o003e94")> このような文字列がたくさん取得してしまう感じになってしまいます。 {% for datess in dates %} {{ datess.text }} {% endfor %} .textを加えると何も取得できなくなってしまいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問