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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

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

Q&A

解決済

1回答

1169閲覧

pythonでwebスクレイピングした情報を、csvファイルに出力できません。

YYJP

総合スコア23

Python 3.x

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

0グッド

0クリップ

投稿2019/08/11 09:29

前提・実現したいこと

webスクレイピングで取得した結果をcsvファイルに出力したいのですが、
項目のみが記載された空のcsvファイルが生成されてしまいます。
サイトは下記を参考にしました。

https://qiita.com/kuto/items/9730037c282da45c1d2b
https://arakan-pgm-ai.hatenablog.com/entry/2018/01/17/080000

どのように書き換えたら、検索結果を適切にcsvファイルに出力できるのでしょうか。
何卒、よろしくお願い致します。

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

Traceback (most recent call last): File "C:\Users\xxxx\OneDrive\ドキュメント\studyplan\0810-2.py", line 32, in <module> search_results_df = get_search_results_df() File "C:\Users\xxxx\OneDrive\ドキュメント\studyplan\0810-2.py", line 20, in get_search_results_df url = tag1.select("a")[i].get("href") IndexError: list index out of range

該当のソースコード

python

1from bs4 import BeautifulSoup 2import requests 3import pandas as pd 4import re 5 6def get_search_results_df(): 7 columns = ["rank", "title", "writer", "year", "citations", "url"] 8 df = pd.DataFrame(columns=columns) #表の作成 9 list_keywd = ['脳', '神経' ,'認知'] 10 html_doc = requests.get('https://scholar.google.co.jp/scholar?num=100&q=' + ' '.join(list_keywd)).text 11 soup = BeautifulSoup(html_doc, "html.parser") # BeautifulSoupの初期化 12 tags1 = soup.find_all("h3", {"class": "gs_rt"}) # title&url 13 tags2 = soup.find_all("div", {"class": "gs_a"}) # writer&year 14 tags3 = soup.find_all(text=re.compile("引用元")) # citation 15 16 rank = 1 17 i = 0 18 for tag1, tag2, tag3 in zip(tags1, tags2, tags3): 19 title = tag1.text.replace("[HTML]","") 20 url = tag1.select("a")[i].get("href") 21 writer = tag2.text 22 writer = re.sub(r'\d', '', writer) 23 year = tag2.text 24 year = re.sub(r'\D', '', year) 25 citations = tag3.replace("引用元","") 26 se = pd.Series([rank, title, writer, year, citations, url], columns) 27 df = df.append(se, columns) 28 rank += 1 29 i += 1 30 return df 31 32search_results_df = get_search_results_df() 33filename = "Google_Scholar.csv" 34search_results_df.to_csv('/Users/yukak/OneDrive/filename', encoding="utf-8") 35 36

試したこと

変数urlを出力したところ、以下のようになったので、
for文ループの途中までは、値は取得できているようです。

https://ci.nii.ac.jp/naid/50002355137/
http://jlc.jst.go.jp/JST.JSTAGE/apr/22.130?from=Google
https://www.jstage.jst.go.jp/article/jcns/18/4/18_KJ00005587432/_article/-char/ja/
https://www.jstage.jst.go.jp/article/jcns/10/10/10_KJ00002978249/_article/-char/ja/
https://ci.nii.ac.jp/naid/110006484978/
http://www.academia.edu/download/43942189/Social_cognition_of_schizophrenia_bridgi20160321-14427-2daer7.pdf
https://www.jstage.jst.go.jp/article/ojjscn1969/28/5/28_5_418/_article/-char/ja/
http://jlc.jst.go.jp/DN/JALC/00080622550?from=Google
https://www.jstage.jst.go.jp/article/jjrm1964/32/10/32_10_670/_article/-char/ja/
https://www.jstage.jst.go.jp/article/fpj/125/2/125_2_68/_article/-char/ja/
Traceback (most recent call last):
File "C:\Users\yukak\OneDrive\ドキュメント\studyplan\0810-2.py", line 33, in <module>
search_results_df = get_search_results_df()
File "C:\Users\yukak\OneDrive\ドキュメント\studyplan\0810-2.py", line 20, in get_search_results_df
url = tag1.select("a")[i].get("href")
IndexError: list index out of range

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

url = tag1.select("a")[i].get("href")
IndexError: list index out of range

tag1.select("a")[i] の部分で tag1.select("a") が配列を返しますが、
i番目の要素がないので IndexError だよ、ということです。
i番目の要素がない場合に、どういう処理が適切なのかは、ちょっとこのケースでは定かではないですが、

tag1_a_list = tag1.select("a") if len(tag1_a_list) > i: url = tag1_a_list[i].get("href") else: このときどうするか? break?? url= "<empty>" とでもする?

などと一回チェックすると、エラーは回避できると思います。

投稿2019/08/11 10:03

mokemokechicken

総合スコア948

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

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

YYJP

2019/08/11 13:55 編集

書いて頂いた通りに、やってみたところ、 ループのエラーがなくなり、ファイルに内容が出力されるようになりました! ありがとうございます!! もう一点、お伺いさせて頂けると嬉しいのですが、 生成されるファイルですが、 「Google_Scholar.csv」ではなく、 「filename」というものが生成されてしまい、内容もひらがな、漢字の箇所が文字化けしてしまいます。(数字、アルファベットは問題ないです) 以下の部分の書き方に問題があるのだと思いますが、どこがおかしいのか、 お教え頂けないでしょうか? 何卒、よろしくお願い申し上げます。 ------------------------------------------------------------------------------------------- search_results_df = get_search_results_df() filename = "Google_Scholar.csv" search_results_df.to_csv('/Users/yukak/OneDrive/filename', encoding="utf-8") ------------------------------------------------------------------------------------------
mokemokechicken

2019/08/11 13:59

その書き方だと filename がそのまま文字列として扱われてしまいますね。 Python3.6以上なら f文字列 という書き方を使って search_results_df.to_csv(f'/Users/yukak/OneDrive/{filename}', encoding="utf-8") と書くことができます。 ※ f文字列の詳細はぐぐるとわかりやすい記事がたくさんあります そうでないならば、 search_results_df.to_csv('/Users/yukak/OneDrive/' + filename, encoding="utf-8") と単純に文字列の連結を使うと良いと思います。
mokemokechicken

2019/08/11 14:04

文字化けは、 print(search_results_df) としたときに既に文字化けしているかどうかで、対応が変わると思います。 print時文字化けしていないなら、csvの内容を確認するときに使ったViewerがutf-8を扱えていない可能性があります。何か別の手段で再確認してみてください。どんな手段で見てみても化けているようなら、どういう風に化けているかも割と大事です。 print時に文字化けしているなら、またちょっと面倒な感じにはなりますね...
YYJP

2019/08/12 09:20

ご返信が遅くなってしまい、申し訳ありません。 filenameについて、f文字列を試したところ、csvファイルが生成されるようになりました! ありがとうございます!! 文字化けについては、search_results_dfの時点では文字化けしていないようでしたが、 どのViewerを使っている等調べるのに少し時間がかかりそうなので、 目下のところは英語のサイトのみ情報を集め、頂いたアドバイスに基づいて、 後日、また文字化け問題に取り組めたらと思います。 本当に、助かりました。 ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問