https://openweathermap.org/city/1850144⇦このサイトの天気情報↓
html
1<div id="weather-widget" class="weather-widget" 2><h2 class="weather-widget__city-name">Weather in Tōkyō-to, JP</h2> 3<h3 class="weather-widget__temperature"><img class="weather-widget__img" src="https://openweathermap.org/img/w/09d.png" alt="Weather Tōkyō-to , JP" width="50" height="50">18 °C</h3> 4 5<p class="weather-widget__main">shower rain</p><!--この部分を取得したい--> 6 7</div>
をスクレイピングしたくて下記のように書いてみたのですが
python
1import requests 2from bs4 import BeautifulSoup 3#目的のURL 4url = "https://openweathermap.org/city/1850144" 5#HTTPリクエスト 6r = requests.get(url) 7# 8bsObj = BeautifulSoup(r.content,"html.parser") 9# 10today = bsObj.find(class_="weather-widget") 11# 12weather = today.p.string 13print("天気:{}".format(weather)) 14
このようなエラーメッセージが出てしまい困っています。
一応調べてみるとインスタンスがp属性を持っていないということらしいんですが。。。
何を改善したらshower rainが取得出来るでしょうか??
AttributeError Traceback (most recent call last) <ipython-input-31-6eec385d0b95> in <module>() 10 today = bsObj.find(class_="weather-widget") 11 # ---> 12 weather = today.p.string 13 print("天気:{}".format(weather)) AttributeError: 'NoneType' object has no attribute 'p'
そもそも論なのですが、なぜWeather APIを利用されないのでしょうか?
APIの知識が全くない為スクレイピングしようかなと思いまして。。APIの方が良いですかね。。
はい。また、規約でスクレイピングが禁止されている可能性があります。確認ください。
ありがとうございます。確認してみます。
取りたい部分が動的に生成されていて、単純にHTTPリクエストで取ってきただけでは取れないパターンかと。selenium等で処理すればできると思いますが、それならAPIを使ったほうが楽だと思いますよ
あーなるほど。。pタグの中が変わってしまって駄目という感じですかね。。ありがとうございます!
そもそもtoday本体が存在しないですね。HTTPリクエストで何が返っているかはr.textで確認できるので、ファイルに吐いて検索すればclass="weather-widget"の要素そのものがないことが納得できるはずです
いや、NoneType~なので、class_="weather-widget"な要素todayから獲れてないです。
えっと、凄くアホな質問だと思うんですがなぜないんでしょうか?検証したところあったはずなんですが。。。
検証したのは要素が描画されてからですよね。その要素の描画はおそらくJavaScriptが動的にクライアントサイドで行っています。HTTPリクエストで直接落としてきた場合はJavaScriptは実行されないので、「HTMLの中に埋め込まれた描画処理を行うJavaScript」は取れますが、それによって描画されたものは取れないですね
あーなるほど。。そういうことだったんですね。。丁寧に教えていただきありがとうございます!
あなたの回答
tips
プレビュー