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

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

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

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

Python

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

Q&A

解決済

1回答

3321閲覧

ホームズの賃貸情報取得

manatahasu

総合スコア1

スクレイピング

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

Python

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

0グッド

0クリップ

投稿2021/10/25 06:08

ホームズ スクレイピング

スーモでは同様の使用でデータを取得できましたが、ホームズではできませんでした。

発生している問題・エラーメッセージ

page 1 items 0 page 2 items 0 page 3 items 0 page 4 items 0    : page 875 items 0 と表示されエラーが出ません。

該当のソースコード

python

1```from retry import retry 2import requests 3from bs4 import BeautifulSoup 4import pandas as pd 5 6base_url = "https://www.homes.co.jp/search/condition1/?page={}" 7 8@retry(tries=3, delay=10, backoff=2) 9def get_html(url): 10 r = requests.get(url) 11 soup = BeautifulSoup(r.content, "html.parser") 12 return soup 13 14all_data = [] 15max_page = 875 16 17for page in range(1, max_page+1): 18 url = base_url.format(page) 19 20 soup = get_html(url) 21 22 items = soup.findAll("div", {"class": "moduleInner prg-building"}) 23 print("page", page, "items", len(items)) 24 25 for item in items: 26 stations = item.findAll("span", {"class": "prg-stationText"}) 27 28 for station in stations: 29 base_data = {} 30 base_data["名称"] = item.find("span", {"class": "bukkenName prg-detailLinkTrigger"}).getText().strip() 31 base_data["カテゴリー"] = item.find("span", {"class": "bType"}).getText().strip() 32 base_data["アドレス"] = item.find("div", {"class": "bukkenSpec"}).findAll("td")[0].getText().strip() 33 base_data["アクセス"] = station.getText().strip() 34 base_data["築年数"] = item.find("div", {"class": "bukkenSpec"}).findAll("td")[2].getText().strip() 35 base_data["構造"] = item.find("div", {"class": "bukkenSpec"}).findAll("td")[2].getText().strip() 36 37 38 tbodys = item.find("table", {"class": "unitSummary unitResidenceSummary"}).findAll("tbody") 39 40 for tbody in tbodys: 41 data = base_data.copy() 42 data["階数"] = tbody.findAll("td")[1].findAll("li")[0].getText().strip() 43 data["家賃"] = tbody.findAll("td")[2].getText().strip() 44 data["管理費"] = tbody.findAll("td")[2].getText().strip() 45 data["敷金"] = tbody.findAll("td")[2].getText().strip() 46 data["礼金"] = tbody.findAll("td")[2].getText().strip() 47 data["間取り"] = tbody.findAll("td")[3].getText().strip() 48 data["面積"] = tbody.findAll("td")[3].getText().strip() 49 50 data["URL"] = tbody.findAll("td")[5].find("a").get("href") 51 52 all_data.append(data) 53 54df = pd.DataFrame(all_data) 55df.to_csv('211025_23区.csv', encoding='utf_8_sig') 56 57### 試したこと 58 59 60 61### 補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

1T2R3M4

2021/10/25 06:10

インデントを正しくつけていないからでは。
manatahasu

2021/10/25 06:19

from retry import retry import requests from bs4 import BeautifulSoup import pandas as pd base_url = "https://www.homes.co.jp/search/condition1/?page={}" @retry(tries=3, delay=10, backoff=2) def get_html(url): r = requests.get(url) soup = BeautifulSoup(r.content, "html.parser") return soup all_data = [] max_page = 875 for page in range(1, max_page+1): url = base_url.format(page) soup = get_html(url) items = soup.findAll("div", {"class": "moduleInner prg-building"}) print("page", page, "items", len(items)) for item in items: stations = item.findAll("span", {"class": "prg-stationText"}) for station in stations: base_data = {} base_data["名称"] = item.find("span", {"class": "bukkenName prg-detailLinkTrigger"}).getText().strip() base_data["カテゴリー"] = item.find("span", {"class": "bType"}).getText().strip() base_data["アドレス"] = item.find("div", {"class": "bukkenSpec"}).findAll("td")[0].getText().strip() base_data["アクセス"] = station.getText().strip() base_data["築年数"] = item.find("div", {"class": "bukkenSpec"}).findAll("td")[2].getText().strip() base_data["構造"] = item.find("div", {"class": "bukkenSpec"}).findAll("td")[2].getText().strip() tbodys = item.find("table", {"class": "unitSummary unitResidenceSummary"}).findAll("tbody") for tbody in tbodys: data = base_data.copy() data["階数"] = tbody.findAll("td")[1].findAll("li")[0].getText().strip() data["家賃"] = tbody.findAll("td")[2].getText().strip() data["管理費"] = tbody.findAll("td")[2].getText().strip() data["敷金"] = tbody.findAll("td")[2].getText().strip() data["礼金"] = tbody.findAll("td")[2].getText().strip() data["間取り"] = tbody.findAll("td")[3].getText().strip() data["面積"] = tbody.findAll("td")[3].getText().strip() data["URL"] = tbody.findAll("td")[5].find("a").get("href") all_data.append(data) df = pd.DataFrame(all_data) df.to_csv('211025_23区.csv', encoding='utf_8_sig') 失礼しました、該当ソースコードにインデント反映されていませんでした。 上記なのでインデントは問題ないと思います。
KojiDoi

2021/10/25 06:38

どこをどう見れば「上記なのでインデントは問題ない」という認識に至れるのでしょうか。
guest

回答1

0

ベストアンサー

ブラウザででのリクエストとこういったライブラリでのリクエストは、リクエストヘッダーなどの設定などを含めて差異があります。
最小コードで実際にどういうレスポンスが来るかを見てからコードを書き進めたほうが良い気がします。

少なくとも、自身の環境では以下のコードで、

python

1import requests 2 3url = "https://www.homes.co.jp/search/condition1/?page=1" 4 5print(requests.get(url).text)

以下の内容が出力されています。

text

1(前略) 2 <h2 style="margin-top: 0;">リクエストがブロックされました!</h2> 3 <p>あなたのリクエストがボットからのアクセスと判断されました。この画面が表示される理由はいくつかあります。 4 </p> 5(後略)

スクレイピング対策が取られています。
規約としてどうかは別として、スクレイピング対策となる実装がされている以上、やめたほうが良いと思います。

投稿2021/10/25 12:37

編集2021/10/25 12:39
attakei

総合スコア2740

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問