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

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

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

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

Python 3.x

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

Q&A

解決済

1回答

2941閲覧

python3 / beautifulsoup / google検索結果スクレイピングにおける検索ワードのCSV読み込み

sadie

総合スコア18

スクレイピング

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

Python 3.x

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

0グッド

0クリップ

投稿2018/10/15 07:57

google検索結果をスクレイピングするにあたり
検索ワードの組み合わせを以下のコードにある組合せ以外に数10通り使い結果を収集したいです
複数の検索ワードを読み込ませる部分のコードの組み方についてご教示頂きたくうかがいます
現在作ったコードは以下です

python3

1import requests as web 2import bs4 3import csv 4 5list_keywd = ['金属屋根','修理','神奈川'] 6resp = web.get('https://www.google.co.jp/search?num=100&q=' + ' '.join(list_keywd)) 7resp.raise_for_status() 8 9soup = bs4.BeautifulSoup(resp.text, "html.parser") 10 11link_elem01 = soup.select('.r > a') 12 13link_elem02 = soup.select('.s > .st') 14 15if(len(link_elem02) <= len(link_elem01)): 16 leng = len(link_elem02) 17else: 18 leng = len(link_elem01) 19 20with open('vvv.csv','w',newline='',encoding='utf8') as outcsv: 21 csvwriter = csv.writer(outcsv) 22 csvwriter.writerow(['タイトル・説明','URL']) 23 for i in range(leng): 24 25 url_text = link_elem01[i].get('href').replace('/url?q=','') 26 27 from urllib.parse import urlparse 28 parsed_url = urlparse(url_text) 29 base_url = '{0.scheme}://{0.netloc}/'.format(parsed_url) 30 31 title_text = link_elem01[i].get_text() 32 33 t01 = link_elem02[i].get_text() 34 t02 = t01.replace('\n','') 35 disc_text = t02.replace('\r','') 36 csvwriter.writerow([title_text + disc_text, base_url]) 37 outcsv.close()

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

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

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

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

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

tiitoi

2018/10/15 08:16

具体的にどこらへんがわからないのでしょうか? keyword_sets = [ ['金属屋根','修理','神奈川'], ['キーワード1','修理','東京'], ['キーワード2','修理','名古屋'], ['キーワード3','修理','福岡'], ['キーワード4','修理','北海道']] のようにリストで定義しとくのでは駄目なのでしょうか?
sadie

2018/10/15 08:21

先程に引き続き、ありがとうございます。初心者につき、そのリストで定義する場合のコードの具体と、そのリストの具体も含め伺いました
guest

回答1

0

ベストアンサー

このような感じでどうでしょうか?
何度か試していたら、Google にBOTと判定されて取得できなくなってしまったので、結果は確認できていません。

python

1import csv 2import requests as web 3from urllib.parse import urlparse 4from bs4 import BeautifulSoup 5 6keyword_sets = [['金属屋根','修理','神奈川'], 7 ['瓦屋根','補修','東京']] 8 9def google(keywords): 10 url = 'https://www.google.co.jp/search?num=100&q=' + ' '.join(keywords) 11 print('googling... ', url) 12 13 # URL から HTML を取得する。 14 resp = web.get(url) 15 # HTML から BeautifulSoup オブジェクトを作成する。 16 soup = BeautifulSoup(resp.text, "html.parser") 17 18 results = [] 19 # URL、タイトル、説明を取得する。 20 # <div class="g"> のタグ一覧を取得する。 21 for div_elems in soup.select('div.g'): 22 # class="r" のタグ配下の a タグを取得する。 23 a_elem = div_elems.select('.r > a') 24 # class="s" のタグ配下の class="st" のタグを取得する。 25 div_elem = div_elems.select('.s > .st') 26 # 両方存在しない場合があったので、その場合はスキップする。 27 if not a_elem or not div_elem: 28 continue 29 # select() は選択された要素が1つでもリストで返すので、1個目の要素を取り出す。 30 a_elem, div_elem = a_elem[0], div_elem[0] 31 32 # a_elem タグの href 属性を取得し、'/url?q=' を削除する。 33 url = a_elem.get('href').replace('/url?q=', '') 34 # ドメイン部分までを取得する。 35 url_prefix = '{0.scheme}://{0.netloc}/'.format(urlparse(url)) 36 # a タグのテキストを取得する。 37 title = a_elem.text 38 # 説明文を取得する。改行コードは削除する。 39 description = div_elem.text.replace('\n','').replace('\r','') 40 # ドメイン部分までの URL、タイトル、説明をリストに追加する。 41 results.append([url_prefix, title, description]) 42 43 return results 44 45results = [] 46# キーワード分検索を実行する。 47for keywords in keyword_sets: 48 results.extend(google(keywords)) 49print(results) 50 51# CSV に書き込む。 52with open('output.csv', 'w', encoding='utf8') as f: 53 writer = csv.writer(f) 54 writer.writerow(['タイトル・説明','URL']) # ヘッダーを書き込む。 55 writer.writerows(results) # データを書き込む。

投稿2018/10/15 09:04

編集2018/10/15 11:06
tiitoi

総合スコア21954

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

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

sadie

2018/10/15 10:46

ご教授ありがとうございます 定義したCSVに情報が書き込まれないのと 取得できる情報も従前のコードに比べて不要な情報が増えてしまったように感じます (前回教えていただいたコードではURLがドメインまでになるようになったのですが今回はドメインより後のURL情報を得てしまいます) 初心者にて申し訳ありません 引き続き、ご教授頂ければ幸いです
tiitoi

2018/10/15 11:08

CSVに情報が書き込まれない件はコードにミスがあったので修正しました。 すみませんが、Google に Bot と判定されて検索結果ページの取得ができなくなってしまったので、コードを実際に試すことはできない状況です。 サンプルコードにコメントを入れといたので、print() デバッグしながら、意図どおり動かせるようにがんばってみてください。 不明な行があれば聞いていただければ、答えます。
sadie

2018/10/15 11:38

ありがとうございます 各コードにコメントをつけて頂き、すごく勉強になります 感動です ありがとうございます 無事CSVに結果を得れたのですが、一点、お教え頂きたいです このコードだと、検索結果におけるオーガニック上位のいくつまで取得するという設定になるのでしょうか?
tiitoi

2018/10/15 11:47 編集

オーガニック上位とは検索表示順のことでしょうか? その場合、以下のようにカウント用の変数 i を追加して、i > 5 となったら for 文を break すればよいと思います。(この場合、上位5位まで) for i, div_elems in enumerate(soup.select('div.g')):
sadie

2018/10/15 12:14

ありがとうございます オーガニック上位とは検索表示順のことです 表示順を上位何件までprintするか、という数が当初のコードにはあったので それがない場合、どこまで取得するということになるのか理解を得たく質問しました 例えば5位までにしようとした場合 いろいろ試してみたんですが頂いた一文 for i, div_elems in enumerate(soup.select('div.g')): 入れる場所は # <div class="g"> のタグ一覧を取得する。 でしょうか? てにをはレベルになり恐縮です
tiitoi

2018/10/15 12:26

挿入場所はそこで大丈夫です。 for i, div_elems in enumerate(soup.select('div.g')) は i = 0, div_elems = div class="g" のタグ (1位のリンク) i = 1, div_elems = div class="g" のタグ (2位のリンク) i = 2, div_elems = div class="g" のタグ (3位のリンク) ... とループが回っていくので、i の値を見てループを抜ければ、例えば上位3位だけデータを抽出できます。
sadie

2018/10/15 12:47

ありがとうございます for div_elems in soup.select('div.g'): と for i, div_elems in enumerate(soup.select('div.g')): を差し替えたり iに対して数字を定義したりトライしましたがどうしても動きません 頂いているコードに差し替えるものでしょうか それとも書き加えるものでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問