python3 / beautifulsoup / google検索結果スクレイピングにおける検索ワードのCSV読み込み
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 2,031
google検索結果をスクレイピングするにあたり
検索ワードの組み合わせを以下のコードにある組合せ以外に数10通り使い結果を収集したいです
複数の検索ワードを読み込ませる部分のコードの組み方についてご教示頂きたくうかがいます
現在作ったコードは以下です
import requests as web
import bs4
import csv
list_keywd = ['金属屋根','修理','神奈川']
resp = web.get('https://www.google.co.jp/search?num=100&q=' + ' '.join(list_keywd))
resp.raise_for_status()
soup = bs4.BeautifulSoup(resp.text, "html.parser")
link_elem01 = soup.select('.r > a')
link_elem02 = soup.select('.s > .st')
if(len(link_elem02) <= len(link_elem01)):
leng = len(link_elem02)
else:
leng = len(link_elem01)
with open('vvv.csv','w',newline='',encoding='utf8') as outcsv:
csvwriter = csv.writer(outcsv)
csvwriter.writerow(['タイトル・説明','URL'])
for i in range(leng):
url_text = link_elem01[i].get('href').replace('/url?q=','')
from urllib.parse import urlparse
parsed_url = urlparse(url_text)
base_url = '{0.scheme}://{0.netloc}/'.format(parsed_url)
title_text = link_elem01[i].get_text()
t01 = link_elem02[i].get_text()
t02 = t01.replace('\n','')
disc_text = t02.replace('\r','')
csvwriter.writerow([title_text + disc_text, base_url])
outcsv.close()
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
このような感じでどうでしょうか?
何度か試していたら、Google にBOTと判定されて取得できなくなってしまったので、結果は確認できていません。
import csv
import requests as web
from urllib.parse import urlparse
from bs4 import BeautifulSoup
keyword_sets = [['金属屋根','修理','神奈川'],
['瓦屋根','補修','東京']]
def google(keywords):
url = 'https://www.google.co.jp/search?num=100&q=' + ' '.join(keywords)
print('googling... ', url)
# URL から HTML を取得する。
resp = web.get(url)
# HTML から BeautifulSoup オブジェクトを作成する。
soup = BeautifulSoup(resp.text, "html.parser")
results = []
# URL、タイトル、説明を取得する。
# <div class="g"> のタグ一覧を取得する。
for div_elems in soup.select('div.g'):
# class="r" のタグ配下の a タグを取得する。
a_elem = div_elems.select('.r > a')
# class="s" のタグ配下の class="st" のタグを取得する。
div_elem = div_elems.select('.s > .st')
# 両方存在しない場合があったので、その場合はスキップする。
if not a_elem or not div_elem:
continue
# select() は選択された要素が1つでもリストで返すので、1個目の要素を取り出す。
a_elem, div_elem = a_elem[0], div_elem[0]
# a_elem タグの href 属性を取得し、'/url?q=' を削除する。
url = a_elem.get('href').replace('/url?q=', '')
# ドメイン部分までを取得する。
url_prefix = '{0.scheme}://{0.netloc}/'.format(urlparse(url))
# a タグのテキストを取得する。
title = a_elem.text
# 説明文を取得する。改行コードは削除する。
description = div_elem.text.replace('\n','').replace('\r','')
# ドメイン部分までの URL、タイトル、説明をリストに追加する。
results.append([url_prefix, title, description])
return results
results = []
# キーワード分検索を実行する。
for keywords in keyword_sets:
results.extend(google(keywords))
print(results)
# CSV に書き込む。
with open('output.csv', 'w', encoding='utf8') as f:
writer = csv.writer(f)
writer.writerow(['タイトル・説明','URL']) # ヘッダーを書き込む。
writer.writerows(results) # データを書き込む。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.33%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
tiitoi
2018/10/15 17:16
具体的にどこらへんがわからないのでしょうか? keyword_sets = [ ['金属屋根','修理','神奈川'], ['キーワード1','修理','東京'], ['キーワード2','修理','名古屋'], ['キーワード3','修理','福岡'], ['キーワード4','修理','北海道']] のようにリストで定義しとくのでは駄目なのでしょうか?
sadie
2018/10/15 17:21
先程に引き続き、ありがとうございます。初心者につき、そのリストで定義する場合のコードの具体と、そのリストの具体も含め伺いました