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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python 3.x

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

Q&A

解決済

2回答

328閲覧

webスクレイピングで語呂合わせを抽出

yy-_.15

総合スコア17

Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python 3.x

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

0グッド

0クリップ

投稿2020/10/27 15:00

編集2020/10/29 04:18

以下(↓より下)のコードを実行し、あるサイトから語呂合わせを57個抽出する作業をしているのですが、
最後のelemsssのみどうしても空リストで返ってきてしまいます。
また、elemsss = soup.select("#detail > div.bg.bg-theme.border.type-detail > div > div > article > div:nth-child(5) > ul")[0].text
このように指定すると、IndexError: list index out of rangeが発生してしまいます。
どうにか語呂合わせを抽出できないでしょうか?


import requests

from bs4 import BeautifulSoup

b = []
for i in range(1,58):
url = "https://input.medilink-study.com/detail.php?index=" + str(i)
b.append(url)

elemss = []
elemsss = []

for i in b:

res = requests.get(i) k = res.text soup = BeautifulSoup(k,'html.parser') elems = soup.select("#detail > header > h1")[0].string print(elems) try: elemss = soup.select("#detail > div.bg.bg-theme.border.type-detail > div > div > article > h2")[0].text print(elemss) except IndexError: continue elemsss = soup.select("#detail > div.bg.bg-theme.border.type-detail > div > div > article > div:nth-child(5) > ul") print(elemsss)

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

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

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

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

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

Takumiboo

2020/10/27 16:32

IndexError: list index out of range のエラーの意味は理解していますか?
yy-_.15

2020/10/28 01:21

今回は空リストのため、インデックスを指定してもエラーが発生するのではないかと 思っています!
Takumiboo

2020/10/28 02:02

では、そこを改善するだけですね。
yy-_.15

2020/10/28 02:20

なぜ空リストになってしまうのでしょうか?
Takumiboo

2020/10/28 02:36

それはページの内容を見ないと分かりませんが、単純に考えたらページの構造とスクレイピングするパスの指定が食い違っているのではないでしょうかね。
yy-_.15

2020/10/28 02:39

抜き出したい場所を選択、右クリックでcopy selectorで きちんと抜き出したつもりではいるのですが。。
guest

回答2

0

ベストアンサー

ログインが必要なページとなっている様ですが
ログイン処理を行っているといった前提であれば以下でそれぞれが取得可能だと思います。

python

1import requests 2from bs4 import BeautifulSoup 3import time 4 5url = "https://input.medilink-study.com/detail.php?index={}" 6for i in range(1, 58): 7 res = requests.get(url.format(i)) 8 soup = BeautifulSoup(res.content, 'html.parser') 9 # お題と回答の取得 10 elements = soup.select('.heading') 11 title = elements[0].string 12 answer = elements[1].text 13 14 # 解説の取得 15 elements2 = soup.select("#detail > div.bg.bg-theme.border.type-detail > div > div > article > div:nth-child(5) > ul") 16 commentaries = [cmt.text for cmt in elements2] 17 time.sleep(1)

追記

上記ではログインしている事を前提で~と回答を致しましたが
恐らくは質問者様はスクレイピングの際にログイン処理は行っていないでしょう。
ログイン処理については恐らくはseleniumを使用した方が簡易的でしょう。
となると、各項の取得もrequestsを使用するのではなくselenium上で取得を行い
driver.page_sourceでソースを取得しBSで各要素を出力するというのがベストな方法だと思います。

python

1from selenium import webdriver 2from selenium.webdriver.chrome.options import Options 3from bs4 import BeautifulSoup 4import time 5 6idpw = ('ID', 'PASSWORD') 7url = 'https://input.medilink-study.com/index.php' 8target = "https://input.medilink-study.com/detail.php?index={}" 9 10 11options = Options() 12options.add_argument('--headless') # ←コメントアウトでヘッドレスモード解除 13driver = webdriver.Chrome(chrome_options=options) 14driver.implicitly_wait(10) 15driver.get(url) 16 17# ログイン処理 18login_button = driver.find_element_by_class_name('icon-login').click() 19driver.find_element_by_class_name('cmn-form-userid').send_keys(idpw[0]) 20driver.find_element_by_class_name('cmn-form-password').send_keys(idpw[1]) 21driver.find_element_by_class_name('cmn-form-login-button').click() 22time.sleep(5) 23 24 25for i in range(1, 58): 26 driver.get(target.format(i)) 27 html = driver.page_source 28 soup = BeautifulSoup(html, 'html.parser') 29 30 # お題と回答の取得 31 elements = soup.select('.heading') 32 title = elements[0].string 33 answer = elements[1].text 34 35 # 解説の取得 36 elements2 = soup.select("#detail > div.bg.bg-theme.border.type-detail > div > div > article > div:nth-child(5) > ul > li") 37 commentaries = {} 38 if len(elements2) != 0: 39 for cmt in elements2: 40 key, value = cmt.select('div') 41 key, value = key.text, value.text 42 commentaries[key] = value 43 # 解説要素がなかった場合 44 else: 45 commentaries = 'comment was none' 46 47 print(title, answer) 48 print(commentaries) 49 print('='*50) 50 time.sleep(1)

投稿2020/10/28 04:54

編集2020/10/28 05:52
nto

総合スコア1438

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

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

Takumiboo

2020/10/28 07:19

っていうところまで質問者さんに気づいていただきたかったんですけどね…。
nto

2020/10/28 07:42

質問者様はやりたい事は明示的、コードを書くという事(行動)はできる ただ、実践的なコードの扱い方はまだ初心者であると判断し、今回追記を致しました。 具体的にはfor文あたりがもう少し正確にかけていたならば、追記でコードの提示はしないつもりでしたが、、、 あとは個人的に、出来ていないとわかっていながら「ログイン処理を行っているといった前提であれば」といった回答も嫌味ったらしく感じてしまい追記を行いました。
yy-_.15

2020/10/28 15:15

なるほど、ログインの状態がリストを取得できるか左右していたのですね。。。 気づけなくて申し訳ないです。。勉強不足なのでまたしっかり出直してきます! お二人の方、ありがとうございました!!!
guest

0

https://input.medilink-study.com/detail.php?index=1にアクセスしてみましたが、#detail > div.bg.bg-theme.border.type-detail > div > div > article > div:nth-child(5) > ulは存在しませんでした。
ログイン状態によって表示内容が異なるのでは?

ところで、サービスによってはスクレイピングが禁止されていることもありますが、そのあたりは大丈夫なんですかね。

投稿2020/10/28 02:45

Takumiboo

総合スコア2534

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

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

yy-_.15

2020/10/28 03:07

そうなんですね! 個人的に抜き出したいテキスト部分にJavascriptが使用されているため, selectでは抜き出せないのかと思っているのですがどうでしょうか? すみません、社に問い合わせてみます
yy-_.15

2020/10/28 03:12

たぶんログインされていないため、#detail > div.bg.bg-theme.border.type-detail > div > div > article > div:nth-child(5) > ulは存在していないのだと思います。 こちらは詳細解説の方にあるものですので
Takumiboo

2020/10/28 04:35

ではそれが原因でしょうね。
yy-_.15

2020/10/28 07:20

Javascriptが使用されているかどうかはどのようにして見分ければ良いのでしょうか?
yy-_.15

2020/10/28 07:20

また、Javascriptが使用されている場合、Xpathなどを使用すればよいでしょうか? 連投すみません。。
Takumiboo

2020/10/28 07:22

どこからJavaScriptの話になりましたか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問