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

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

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

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

Django

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Python

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1477閲覧

pythonでHTMLでのテーブルを使ってfor文を使ってデータを格納したいが上手く表示されない

sakanaku

総合スコア17

スクレイピング

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

Django

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Python

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/10/05 15:46

編集2020/10/06 03:35

前提・実現したいこと

こんにちわ。
pythonでのhtmlでテーブルを作成してのfor文でデータをテーブルに一列づついれたいのですが、上手くいきません。
DjangoORMで取得した、
content.nameに["名前","名前","名前","名前",]
content.linkに["リンク先","リンク先","リンク先",]
content.dateに["日付","日付",]"日付",]
のデータが入っています。
こちらをテンプレートでテーブルを使ってうまく列に格納させて表示させたいのですが上手くいきません。
ーーー
名前 リンク先 日付
桃   http:// 2020
りんご http:// 2020
みかん http:// 1999
ーーー
のようにブラウザで表示させたいです。
今は下記のようになってます。
↓↓
ーーー
名前 リンク先 日付

りんご
みかん
http://
http://
http://
2020
2020
1999
ーーー
のように一列になっちゃいます。

こちらindex.htmlでどのようなコードにすると上手くテーブルにデータをfor文を使って格納することができるでしょうか??
ぜひ、ご教授いただきたいです。
よろしくお願いします。

該当のソースード

index.html①

<html> <body> <table> <tr border="1"> <th>名前</th> <th>リンク先</th> <th>日付</th> </tr> {% for x in content.name %} <tr> <td>{{ x }}</td> </tr> {% endfor %} {% for y in content.link %} <tr> <td><a href="{{ y }}">{{ y }}</a></td> </tr> {% endfor %} {% for z in content.date %} <tr> <td>{{ z }}</td> </tr> {% endfor %} </table> </body> </html>

試したこと

index.html②

<html> <body> <table> <tr border="1"> <th>名前</th> <th>リンク先</th> <th>日付</th> </tr> {% for x in content.name %}      {% for y in content.link %}         {% for z in content.date %} <tr>  <td>{{ x }}</td>  <td><a href="{{ y }}">{{ y }}</a></td>    <td>{{ z }}</td>         </tr>  {% endfor %}       {% endfor %} {% endfor %} </table> </body> </html>

このようにindex.html②のようなテンプレートでfor文をかくと多重にデータを取得してしまい100件近く?の同じデータを取得してしまいます。

index.html①のfor文の書き方をデータはしっかり表示させることができているのですが、テーブルに上手く入りません。

該当のソースード

views.py

import chromedriver_binary from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options from .models import Meibo, Content from django.urls import reverse_lazy from django.views.generic import CreateView options = Options() options.headless = True options.add_argument('--headless') driver = webdriver.Chrome(options=options) driver.get( "動的なwebサイト") class Create(CreateView): template_name = 'index.html' model = Meibo fields = ('name', 'link', 'date') success_url = reverse_lazy('lo') def mou(request): arry = [] selector = '日付の要素' element = driver.find_elements_by_css_selector(selector) element = [a.get_attribute("href") for a in element] date_element = "リンク先の要素" dates = driver.find_elements_by_css_selector(date_element) dates = [b.text for b in dates] # print(dates) i = '名前の要素' items = driver.find_elements_by_css_selector(i) items = [c.text for c in items] for x in items: for y in element: for z in dates: arry.append([x, y, z]) table = Company.objects.create(name=items, link=element, date=dates) for e in arry: b = Meibo.objects.create(name=e[0], link=e[1], date=e[2]) param = {'content': table} return render(request, 'index.html', param)

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

mac10.15.3
python3.8

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

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

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

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

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

guest

回答1

0

ベストアンサー

Djangoを使ったことがあるわけではないので間違ってるかもしれませんが、

py

1cons = zip(content.name, content.link, content.date)

のようにzipでまとめて

html

1{% for x, y, z in cons %} 2<tr> 3 <td>{{ x }}</td> 4 <td>{{ y }}</td> 5 <td>{{ z }}</td> 6</tr> 7{% endfor %}

みたいにすればいいんじゃないですかね。
テンプレート中で分割代入が効くかとかは試してないのでわかりませんが…


ちょっとDjangoの記事とか見て手元で動かした結果、スクレイピング部分を省いてテーブルをパラメータに渡してrenderする、というだけなら以下のように書いて動きました。
item, element, datesの中身は適当です。

ご提示いただいたview.pyだけでは他のクラス構造がわからず動かせませんしDjangoORMはちょっとよくわからないです。ごめんなさい。

py

1from django.shortcuts import render 2 3def index(request): 4 items = ['foo', 'bar', 'baz'] 5 element = ['hoge', 'fuga', 'piyo'] 6 dates = range(3) 7 8 param = {'table': zip(items, element, dates)} 9 10 return render(request, 'polls/index.html', param)

html

1<html> 2<body> 3 <table> 4 <tr border="1"> 5 <th>名前</th> 6 <th>リンク先</th> 7 <th>日付</th> 8 </tr> 9 {% for x, y, z in table %} 10 <tr> 11 <td>{{ x }}</td> 12 <td>{{ y }}</td> 13 <td>{{ z }}</td> 14 </tr> 15 {% endfor %} 16 </table> 17</body> 18</html>

結果

投稿2020/10/05 16:27

編集2020/10/06 13:07
kairi003

総合スコア1332

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

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

sakanaku

2020/10/06 03:39

ご回答ありがとうございます。 zip()を使ってテンプレート中で分割代入が効くのですが、DjangoORMのクエリセット自体をfor文で回すことができないようです。 そこで事前にコードを加工すると上手くクエリが回っているみたいなのですが、、、 現在のviews.pyの中身を追加させてもらいましたがここに改善点があるのでしょうか?? すいません、ぜひご教授願いたいです。
sakanaku

2020/10/06 15:28

ささっとzip()使ってコードまで作っていただきありがとうございます。 さらに、ささっとできるなんて羨ましいです。 ご回答ありがとうございました。もう少し調べてみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問