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

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

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

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

Beautiful Soup

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

Python 3.x

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

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

1900閲覧

閲覧にログインが必要なサイトの情報をスクレイピングできない。ログイン前の情報(ログインして閲覧!というボタンの情報など)が取れてしまう。

Jikao

総合スコア7

スクレイピング

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

Beautiful Soup

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

Python 3.x

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

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2022/10/08 02:19

編集2022/10/08 10:39

前提

pythonで特定のWebサイトからデータをスクレイピングするプログラムを作っています。
pythonのバージョンは3.10.7、使用OSはWindows11です。
質問者はpython初心者です。

実現したいこと

https://en-hyouban.com/company/00008059864/

こちらのサイトの、”年収・給与の納得度”、”勤務時間の納得度”、”休日・休暇の納得度”、”職場の人間関係の満足度”の数値を抜き出したいです。まずは”年収・給与の納得度”である「70」という数字をスクレイピングすることを目標にプログラムを書きました。ただし、該当のサイトはアカウントを作ってログインしないと数字が見れない設計になっています。したがって、先ずはSeleniumでログイン処理を行ってから、スクレイピングを行う設計にしました。

”年収・給与の納得度”の箇所に該当するhtmlのコードは、以下になります。

html

1 <div class="mb-2 mt-3"> 2 <div class="d-flex justify-content-between align-items-end"> 3 <span class="fsize-14 font-size-2 font-weight-bold">年収・給与の納得度</span> 4 <span class="font-roboto d-inline-block mb-n1"> 5 <span class="fsize-28 font-change-24 font-weight-bold "> 6 70 7 </span> 8 % 9 </span> 10 </div> 11 <div class="progress rounded-0 h-5 progress-bg"> 12 <div class="progress-bar bg-F89F19 p-w-70"></div> 13 </div> 14</div>

該当のソースコード

ログイン処理を行うところから書くと長すぎてしまうので、該当部分だけを抜き出して書いています。
Seleniumで以下に示すソースコードは、ログイン後、上述のhttps://en-hyouban.com/company/00008059864/に遷移したところから実行するプログラムです。
spanタグで、クラスがfsize-28 font-change-24 font-weight-bold であるものをfindメソッドで取り出しています。
また、該当箇所のCSSセレクタを用いてselectメソッドを用いる手法も試しています。

python

1#インターバルとURLの設定 2INTERVAL = 2.5 3URL = "https://en-hyouban.com/" 4 5#ドライバー設定 6from selenium import webdriver 7driver = webdriver.Chrome(executable_path = "C:\mypg\py\chromedriver.exe")#自分のドライバーのパス 8#サイトにアクセス 9driver.get(URL) 10import time 11time.sleep(INTERVAL) 12 13#ログインボタンをクリック 14ele_btn_log = driver.find_element_by_xpath('//*[@id="company-view-header-menu"]/div[2]/div[1]/a') 15driver.get(ele_btn_log.get_attribute("href")) 16 17time.sleep(INTERVAL) 18 19#ログインIDを記入 20ele_logid = driver.find_element_by_xpath('//*[@id="email"]') 21ele_logid.send_keys(mymail)#自分のメールアドレス 22 23#ログインパスワードを記入 24ele_logpwd = driver.find_element_by_xpath('//*[@id="password"]') 25ele_logpwd.send_keys(mypwd)#自分のパスワード 26 27#ボタンクリック 28ele_btn_log2 = driver.find_element_by_xpath('//*[@id="login-form"]/div[3]/button') 29ele_btn_log2.click() 30time.sleep(INTERVAL) 31 32coop_url = "https://en-hyouban.com/company/00008059864/" 33driver.get(coop_url) 34 35#urlを取得 36res = requests.get(coop_url) 37 38#スープで解析、パーサーはPython’s html.parser 39soup = BeautifulSoup(res.text, "html.parser") 40 41#findメソッドで取り出してみる 42element_find = soup.find("span", class_="fsize-28 font-change-24 font-weight-bold ") 43#selectメソッドで取り出してみる 44element_sel = soup.select("#progressChart1 > div > div.col-sm-12 > div.mb-2.mt-3 > div.d-flex.justify-content-between.align-items-end > span.font-roboto.d-inline-block.mb-n1 > span") 45 46print(element_find) 47print(element_sel)

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

取り出せていません...
ログイン前のデータを取り出してしまっているようです。

python

1None 2[<span class="fsize-28 font-change-24 font-weight-bold"> 3<a href="https://en-hyouban.com/user/register/?companytop_satisfaction"><img alt="hide-salary-size" class="button_register_size2" src="https://d1uoy7w9kqjh3s.cloudfront.net/images/button_register.png"/></a> 4</span>]

試したこと

https://teratail.com/questions/342435などを参照し、回答の手法を試しましたが、目的のデータを得られませんでした。

また、上記WebサイトのcURLをこのページ(https://curlconverter.com/python/)でrequestsに変換したところ、以下のようになりました。

python

1import requests 2 3response = requests.get('http://^')

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

上記pythonコードで抽出した文字列の中に、<a href="https://en-hyouban.com/user/register/?companytop_satisfaction">というタグがありましたが、このリンクに見覚えがあり、調べてみたところログインしていない状態でWebサイトにアクセスしたときに出る、会員登録を促すURLと同一のものでした。ログインなしでアクセスしたときの、htmlソースを以下に付記しておきます。

html

1 <div class="mb-2 mt-3"> 2 <div class="d-flex justify-content-between align-items-end"> 3 <span class="fsize-14 font-size-2 font-weight-bold">年収・給与の納得度</span> 4 <span class="font-roboto d-inline-block mb-n1"> 5 <span class="fsize-28 font-change-24 font-weight-bold "> 6 <a href="https://en-hyouban.com/user/register/?companytop_satisfaction"><img class="button_register_size2" alt="hide-salary-size" src="https://d1uoy7w9kqjh3s.cloudfront.net/webp-images/button_register.webp"></a> 7 </span> 8 % 9 </span> 10 </div> 11 <div class="progress rounded-0 h-5 progress-bg"> 12 <div class="progress-bar bg-F89F19 p-w-70"></div> 13 </div> 14</div>

上記のサイトに関して、スクレイピング対策としてどのような手法を取っているのか、質問タイトルの状態から類推できることがあればご教示いただきたいです。よろしくお願いいたします。

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

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

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

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

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

melian

2022/10/08 02:42

element_sel = soup.select_one('span:-soup-contains("年収・給与の納得度") + span') に変更するとどうなりますか?
Jikao

2022/10/08 03:50

コメントありがとうございます。 ご指摘の通りコードを改めたところ、 <span class="font-roboto d-inline-block mb-n1"> <span class="fsize-28 font-change-24 font-weight-bold"> <a href="https://en-hyouban.com/user/register/?companytop_satisfaction"><img alt="hide-salary-size" class="button_register_size2" src="https://d1uoy7w9kqjh3s.cloudfront.net/images/button_register.png"/></a> </span> % </span> という結果が取れました。%は取れているようですが、数字は取得できていないようです,,,。
PondVillege

2022/10/08 07:41 編集

ログイン前のデータを取ってきてしまっているなら,ログイン処理のコードもお願いしてよろしいでしょうか?ログインに必要なユーザ名やPWなどの伏せるべき情報は伏せていただいて大丈夫です. 少なくとも,requests.get()以降が正しいかどうか確かめる方法は存在します. 欲しい数字が見えているページのある状態のときに,次のサイトを使って,cURLをrequests形式に変換するものです.使い方はページ中部に書いてあります. https://curlconverter.com/ これを使うとセッション情報を丸々コピペできますので,SelemiumやWebDriverは不要です.ので,requests.get()以降で欲しい情報が取れているか確認ができる.というわけです.プログラムのファイルを新規作成して実行してみると良いでしょう. これで欲しい数字が取れた場合,SelemiumやWebDriverでのログイン方法が間違っており,ログインしないと得られない情報を抜き取れていない.というように原因の切り分けができます. サービスによってはセッションの存命期間が長い物があるので,しばらくは同じCookiesやHeadersを使いまわしで動くこともあると思います.その際にはログイン処理が不要で便利ですね. ログイン処理を含むと長くなってしまうということで省略いただいていますが,もしセッション丸コピで動くならログイン処理が間違っており,掲載すべきであった.ということになります.
Jikao

2022/10/08 10:16

コメントありがとうございます。 ログイン処理のコードを追記いたしました。ログインする前はenライトハウスのトップページからログインボタンを押してセレニウムでログイン処理を行います。 やり方が正しいかわからないのですが、cURLをrequests形式に変換するサイトで試してみても情報が摂れている様子はないようでした。サイトのダイアログボックス下部に出る領域に欲しい数字がない場合、ログイン処理には問題がない、という解釈でよろしいのですよね。
PondVillege

2022/10/08 11:06 編集

少し心が引けたのですが会員登録してみて,cURL to Requestsを試してみたところ,70という数字を得ることができました.そちらでは恐らく正しいcURLをコピペできていないのでしょう.開発者ツールでnetworkのタブのうち,00008059864/が2つ出てきていると思うのですが,Cookie情報がある方が正しいcURLリクエストになります. 少し早まった結論ですが,少なくとも弊環境での実行結果と比較すると,そちらのログイン処理に間違いがあるとしか言いようがありません.
PondVillege

2022/10/08 10:59 編集

編集したものを確認いたしました.うまくcURLを変換サイトにコピペできていないようですね.コピペに成功した場合, import requests cookies = { ......... } headers = { ......... } response = requests.get('https://en-hyouban.com/company/00008059864/', cookies=cookies, headers=headers) のようなコードに変換されると思います.(間違ってもCookieの情報を掲載しないように) また,Cookieを使い回してrequestsに渡すURLを変更するだけで,他の会社の情報も取得できましたこと,報告いたします.
Jikao

2022/10/08 11:34

コメントありがとうございます。 わざわざ会員登録までしてくださり、本当にありがとうございます。 やはりうまくコピーできていませんでしたか...。 お手を煩わせてしまい、大変恐縮です。 Google Chromeでcurlをコピーしようとすると、いくつか選択肢があり、ここで間違えていたようです。 copy as curl(cmd) を選択してしまっていたため、うまくできなかったと思われます。代えて copy as curl(bash) でコピーしたら、書いていただいた通り変換することができました。 また、変換したものからbeautiful soupでテキストを抜き出したところ、うまく”70”を抽出することができました!!! 本当にありがとうございます。このコメントを以って回答とさせていただきます。
PondVillege

2022/10/08 12:08 編集

おめでとうございます.もしセッションの存命期間が短い,もしくは他人にコードを使ってもらう場合にはCookieを晒してしまうことになり,セキュリティに問題(セッションハイジャックされます)があるので,今できていないログイン処理にも手をつけると良いでしょう.お疲れ様でした.
guest

回答3

0

自己解決

cURLからクッキー情報を抜き出し、requestsに付記することで目的のデータを取り出すことができました。問題のコードでは、いきなりrequestsでログイン情報がないと数値が見れないページをリクエストしていたため、うまくいかなかったものと思われます。クッキーとヘッダーの確認については、コメントを参照してください。

最終的に解決したコードを以下に示します。

python

1import requests 2#自分のクッキー情報とヘッダ情報を入れる 3cookies={} 4headers={} 5#クッキー情報とともにリクエスト 6response = requests.get('https://en-hyouban.com/company/00008059864/', cookies=cookies, headers=headers) 7 8from bs4 import BeautifulSoup 9soup = BeautifulSoup(response.text, "html.parser") 10 11element_sel = soup.select_one('span:-soup-contains("年収・給与の納得度") + span') 12 13print(element_sel.contents)

投稿2022/10/08 11:46

Jikao

総合スコア7

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

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

0

てっきり,ログイン処理をSeleniumで行い、その後はrequestsで処理するものかと思っていたら,セッションを渡されていないrequestsで実行されていたのですね,それは当然ログイン前画面が出るかと.リンクのページ同様,セッションの受け渡しを行ってください.

Python

1 2driver = webdriver.Chrome() 3 4#~ログイン処理~ 5 6session = requests.session() 7 8#セッションの受け渡し 9for cookie in driver.get_cookies(): 10 session.cookies.set(cookie["name"], cookie["value"]) 11 12res = session.get(url) 13soup = BeautifulSoup(res.text, "html.parser") 14 15#findメソッドで取り出してみる 16element_find = soup.find_all("span", {"class": "fsize-28 font-change-24 font-weight-bold"}) 17 18for num in element_find: 19 print(num.text.strip())

投稿2022/10/08 11:17

編集2022/10/08 11:34
PondVillege

総合スコア1579

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

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

Jikao

2022/10/08 11:52

回答ありがとうございます。 解決方法が分かって一時間ほど回答を書いていたため、解凍が来ていることに気づかず、自己解決にしてしまいました。 解答のお手数をおかけしてしまい、大変申し訳ないです。 長々とお付き合いいただき、本当にありがとうございました。
PondVillege

2022/10/08 11:53

解決できたことの方が大事なので,お気になさらず
guest

0

ログイン前のデータを取り出してしまっているようです。

最初Seleniumでやってるのに、途中で突然requests.get(coop_url)してますが、requests側ではログイン処理してないので、ログイン前画面が出て当然でしょう。
requestsを使わずウェブアクセスは全部Seleniumでやれば良いだけだと思います。

投稿2022/10/08 11:08

otn

総合スコア84633

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

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

Jikao

2022/10/08 11:54

回答ありがとうございます。 はい...その通りです。 requestsはただ単にページの内容を要求するものなので、クッキー情報なしには会員登録していないユーザーだと解釈される、ということでしたね。 解決方法が分かって一時間ほど回答を書いていたため、解凍が来ていることに気づかず、自己解決にしてしまいました。 解答のお手数をおかけしてしまい、大変申し訳ないです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問