前提・実現したいこと
BeautifulSoup4でGoogleの検索件数を取得したい
発生している問題・エラーメッセージ
[Input] 1 teratail [Output] None Traceback (most recent call last): File "search.py", line 34, in <module> search_keyword(keyword_list) File "search.py", line 25, in search_keyword stats_text = result_stats.text AttributeError: 'NoneType' object has no attribute 'text'
このようにresult_statsが取得できません。
該当のソースコード
Python
1import requests as web 2from bs4 import BeautifulSoup 3 4def create_keyword_list(): 5 N = int(input()) 6 keyword_list = [] 7 for i in range(N): 8 keyword_list.append(input()) 9 return keyword_list 10 11def search_keyword(keyword_list): 12 keyword_dict = {} 13 for keyword in keyword_list: 14 res = web.get("https://www.google.com/search?q={}".format(keyword)) 15 soup = BeautifulSoup(res.text, "html.parser") 16 17 result_stats = soup.find("#result-stats div") 18 print(result_stats) 19 stats_text = result_stats.text 20 stats_text = stats_text.replace("約 ", "").replace(" 件", "").replace(",", "") 21 keyword_dict[keyword] = int(stats_text) 22 23 for k, v in keyword_dict: 24 print(str(k) + "|", str(v)) 25 26if __name__ == '__main__': 27 keyword_list = create_keyword_list() 28 search_keyword(keyword_list)
以下の部分を取得したい。
html
1<div id="result-stats">約 548,000 件<nobr> (0.30 秒) </nobr></div>
試したこと
・soup.find("div", id="result-stats")
など、別の探し方を何パターン化試した。
【追記】
・soup.find("div#result-stats")
・soup.find("#result-stats")
・soup.find('div')とすると、とりあえず値は返ってくる。
・soup.find(nobr)がNone
これらから<nobr>が引っかかっているような気がするのですが、解決策を教えてください。
【追記】
こちらのサイトにあるように、bs4はnobrタグを含む要素を飛ばすようなのですが、情報が少なくてよくわかりませんでした。
nobr以外のdiv要素を読み込むことはできますか?
Google は、HTML の仕様が頻繁に変わると思いますが、Web ブラウザではなく、プログラム ` res = web.get (〜)`の後に ` res.content ` で HTML を確認するとどの様な HTML が取得されていますか?
ご指摘の通り確認したところ、result-statsがありませんでした。https://www.google.com/search?q=keyword、と検索したのですが、ソースコードが若干違うように見えました。
(hタグが全てdivになっているなど)
これを解消する方法はありますか?
Google は、おそらくスクレイピング対策で出力する HTML を変えているのだと思います。
「具体的にこうすれば、同じ出力になる」という情報はほとんどなくて不明なので、試行錯誤するしか無いと思います。
なるほど。ありがとうございます。
でも、調べた感じ厳しそうですね。