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

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

ただいまの
回答率

87.34%

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,155

score 20

前提・実現したいこと

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

該当のソースコード

from bs4 import BeautifulSoup
import requests
import pandas as pd
import re

def get_search_results_df():
    columns = ["rank", "title", "writer", "year", "citations", "url"]
    df = pd.DataFrame(columns=columns) #表の作成
    list_keywd = ['脳', '神経' ,'認知']
    html_doc = requests.get('https://scholar.google.co.jp/scholar?num=100&q=' + ' '.join(list_keywd)).text
    soup = BeautifulSoup(html_doc, "html.parser") # BeautifulSoupの初期化
    tags1 = soup.find_all("h3", {"class": "gs_rt"})  # title&url
    tags2 = soup.find_all("div", {"class": "gs_a"})  # writer&year
    tags3 = soup.find_all(text=re.compile("引用元"))  # citation

    rank = 1
    i = 0
    for tag1, tag2, tag3 in zip(tags1, tags2, tags3):
        title = tag1.text.replace("[HTML]","")
        url = tag1.select("a")[i].get("href")
        writer = tag2.text
        writer = re.sub(r'\d', '', writer)
        year = tag2.text
        year = re.sub(r'\D', '', year)
        citations = tag3.replace("引用元","")
        se = pd.Series([rank, title, writer, year, citations, url], columns)
        df = df.append(se, columns)
        rank += 1
        i += 1
    return df

search_results_df = get_search_results_df()
filename = "Google_Scholar.csv"
search_results_df.to_csv('/Users/yukak/OneDrive/filename', encoding="utf-8")

試したこと

変数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/ツールのバージョンなど)

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

回答 1

checkベストアンサー

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 22:54 編集

    書いて頂いた通りに、やってみたところ、
    ループのエラーがなくなり、ファイルに内容が出力されるようになりました!
    ありがとうございます!!

    もう一点、お伺いさせて頂けると嬉しいのですが、
    生成されるファイルですが、
    「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")
    ------------------------------------------------------------------------------------------

    キャンセル

  • 2019/08/11 22: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")

    と単純に文字列の連結を使うと良いと思います。

    キャンセル

  • 2019/08/11 23:04

    文字化けは、
    print(search_results_df)
    としたときに既に文字化けしているかどうかで、対応が変わると思います。

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

    キャンセル

  • 2019/08/12 18:20

    ご返信が遅くなってしまい、申し訳ありません。
    filenameについて、f文字列を試したところ、csvファイルが生成されるようになりました!
    ありがとうございます!!

    文字化けについては、search_results_dfの時点では文字化けしていないようでしたが、
    どのViewerを使っている等調べるのに少し時間がかかりそうなので、
    目下のところは英語のサイトのみ情報を集め、頂いたアドバイスに基づいて、
    後日、また文字化け問題に取り組めたらと思います。

    本当に、助かりました。
    ありがとうございました!!

    キャンセル

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

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る