🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
スクレイピング

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

Django

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

Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

2789閲覧

Djangoで書かれた?WebサイトをBeautifulSoupでスクレイピングしたい

hiroshimaeasyry

総合スコア15

スクレイピング

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

Django

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

Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/11/05 13:47

https://www.jrf-reit.com/portfolio/list.html

この不動産投資法人の物件一覧ページから、物件名と住所を取得するのが目標です。

python:

1from bs4 import BeautifulSoup 2import requests 3import urllib 4 5url = 'https://www.jrf-reit.com/portfolio/list.html' 6 7res = requests.get(url) 8soup = BeautifulSoup(res.content, 'html.parser') 9print(soup.tbody)

結果

console:

1<tbody v-bind:key="index" v-for="(item, index) in filtered_data"> 2<tr> 3<td class="thumb" rowspan="2"><a class="tbox" v-bind:href="item.url"> 4<div><img alt="" v-bind:src="item.thumb"/><span class="filter"></span></div></a></td> 5<td class="name" rowspan="2"> 6<a v-bind:href="item.url"> 7<p class="summary">{{item.summary}}</p> 8<p class="name" v-html="item.name"></p> 9<p class="area">{{item.addr}}</p> 10</a> 11</td> 12<td class="time" rowspan="2">{{item.date | shortDate}}</td> 13<td class="age" rowspan="2"><span v-if="site == 'IIF'">{{item.build | shortDate}}</span><span v-else="">{{item.build | calcAge}}</span></td> 14<td class="space" rowspan="2">{{item.space | localeString}}</td> 15<td class="price">{{item.price| localeString}}</td> 16<td class="valuation">{{item.valuation| localeString}}</td> 17<td class="tenant">{{item.tenant_num}}</td> 18<td class="op-rate">{{item.op_rate}}</td> 19</tr> 20<tr> 21<td class="price-ratio">{{calcRatio(item.price, total_price)}}</td> 22<td class="value-ratio">{{calcRatio(item.valuation, total_valuation)}}</td> 23<td class="major-tenant" colspan="2"> 24<p><span v-html="item.major_tenant"></span></p> 25</td> 26</tr> 27</tbody>

7-9行目の

<p class="summary">{{item.summary}}</p> <p class="name" v-html="item.name"></p> <p class="area">{{item.addr}}</p>

このあたりが欲しい情報だと思いますが、見ると実際の物件名や住所ではなく、{{item.addr}}などと書かれています。
Djangoのテンプレートエンジンを使ったcontext?のように見えますが、欲しいのはGビル南青山02
東京都港区南青山五丁目8番5号などのような実際の名前です。
このような情報はどうやって取得したらよいのでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

とりあえずSeleniumとheadless chromeで住所取得できます。

python

1from selenium import webdriver 2from selenium.webdriver.chrome.options import Options 3from bs4 import BeautifulSoup 4 5options = webdriver.ChromeOptions() 6options.add_argument('--headless') 7options.add_argument('--no-sandbox') 8options.add_argument('--disable-dev-shm-usage') 9 10driver = webdriver.Chrome('chromedriver', options=options) 11driver.implicitly_wait(10) 12driver.get('https://www.jrf-reit.com/portfolio/list.html') 13 14html = driver.page_source.encode('utf-8') 15 16driver.quit() 17 18soup = BeautifulSoup(html, "html.parser")

住所の番地以外はポートフォリオ一覧(CSV:12.9KB)から取得できるのと

こちらからJavascriptの配列を取得できるのでJSONに変換できそうです
https://www.jrf-reit.com/common/data/object_list.js

JSONに変換

python

1import requests 2import pandas as pd 3 4url = 'https://www.jrf-reit.com/common/data/object_list.js' 5 6r = requests.get(url) 7 8# 変数名と;を除去 9j = r.text.replace("var PORTFOLIO_DATA = ", "").replace('\t"', '"').replace('];', ']') 10 11df = pd.read_json(j) 12 13df.to_csv("result.csv")

投稿2019/11/18 08:45

編集2019/11/21 13:07
barobaro

総合スコア1286

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

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

hiroshimaeasyry

2019/11/21 11:13

ありがとうございます。 やはりseleniumを使わないと、bsだけでは拾えないんですね... こちらのページに関してはおっしゃられる通りread_csv()で取得しましたが、 他のサイトでもこの埋め込み型が出てきた時の為、selenium勉強してみます。 ありがとうございました。
barobaro

2019/11/21 13:02

別にseleniumを使わなくてもjavascript等でレンダリングされたあとのページを取得するばいいだけですのでたくさんのページを取得するのでなければブラウザの名前をつけてページを保存でファイルにしてしまえばスクレイピングできます。
barobaro

2019/11/21 13:08

追記しました。 JSONに変換後、CSVに変換しています。
guest

0

下記で出来ます。

Python

1print(soup.body)

投稿2019/11/07 09:14

yamato_user

総合スコア2321

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

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

hiroshimaeasyry

2019/11/09 09:47

`print(soup.body)` で取得できるのは、やはり実際の物件名や住所ではありません。 例えば `print(soup.select('th')`で表の部分の中身を取得しようとすると、 こちらが返ってきました。 ``` [<th rowspan="3">物件イメージ</th>, <th class="sortable" rowspan="3">物件名称 <div class="arrow"> <span class="asc" v-bind:class="{active:(sort_key == 'name' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('name','A')"></span> <span class="desc" v-bind:class="{active:(sort_key == 'name' &amp;&amp; sort_order == 'D')}" v-on:click="execSort('name','D')"></span> </div> </th>, <th class="sortable" rowspan="3">取得時期 <div class="arrow"> <span class="asc" v-bind:class="{active:(sort_key == 'date' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('date','A')"></span> <span class="desc" v-bind:class="{active:(sort_key == 'date' &amp;&amp; sort_order == 'D')}" v-on:click="execSort('date','D')"></span> </div> </th>, <th class="sortable" rowspan="3"> <span v-if="site == 'IIF'">建築時期</span><span v-else="">築年数(年.ヶ月)</span> <sup>※2</sup> <div class="arrow"> <span class="asc" v-bind:class="{active:(sort_key == 'build' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('build','A')"></span> <span class="desc" v-bind:class="{active:(sort_key == 'build' &amp;&amp; sort_order == 'D')}" v-on:click="execSort('build','D')"></span> </div> </th>, <th class="sortable" rowspan="3">総賃貸可能面積(㎡)<sup>※3</sup> <div class="arrow"> <span class="asc" v-bind:class="{active:(sort_key == 'space' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('space','A')"></span> <span class="desc" v-bind:class="{active:(sort_key == 'space' &amp;&amp; sort_order == 'D')}" v-on:click="execSort('space','D')"></span> </div> </th>, <th class="sortable" rowspan="2">取得価格<br/>(百万円) <div class="arrow"> <span class="asc" v-bind:class="{active:(sort_key == 'price' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('price','A')"></span> <span class="desc" v-bind:class="{active:(sort_key == 'price' &amp;&amp; sort_order == 'D')}" v-on:click="execSort('price','D')"></span> </div> </th>, <th class="sortable" rowspan="2">鑑定評価額・期末算定価額<br/>(百万円)<sup>※4</sup> <div class="arrow"> <span class="asc" v-bind:class="{active:(sort_key == 'valuation' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('valuation','A')"></span> <span class="desc" v-bind:class="{active:(sort_key == 'valuation' &amp;&amp; sort_order == 'D')}" v-on:click="execSort('valuation','D')"></span> </div> </th>, <th colspan="2">テナント<sup>※5</sup></th>, <th class="sortable">数 <div class="arrow"> <span class="asc" v-bind:class="{active:(sort_key == 'tenant_num' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('tenant_num','A')"></span> <span class="desc" v-bind:class="{active:(sort_key == 'tenant_num' &amp;&amp; sort_order == 'D')}" v-on:click="execSort('tenant_num','D')"></span> </div> </th>, <th>稼働率(%)<sup>※6</sup></th>, <th>(%)</th>, <th>(%)</th>, <th colspan="2">主要テナント</th>] ``` `<span class="asc" v-bind:class="{active:(sort_key == 'name' &amp;&amp; sort_order == 'A')}" v-on:click="execSort('name','A')"></span>` ここに名前が入っていると思いますが、実際の名前を拾うにはどうしたらよいでしょうか?
yamato_user

2019/11/11 02:26

print(soup.tbody) ではなく、 print(soup.body) でも無理ですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問