

Python初心者ですみません。あるウェブサイトから、情報を一気に取得したいのですが、ウェブページに多彩なメニューがあり、これら全てを一気に取得する方法などあるでしょうか。  
スクレイピングの基本だと思うのですが、ご支援いただけますと幸いです。

ウェブページは以下のものです。

<https://nintei.nurse.or.jp/certification/General/(X(1)S(efl0y555pect3x45oxjzfw3x))/General/GCPP01LS/GCPP01LS.aspx?AspxAutoDetectCookieSupport=1>

以前に試した方法として、以下のようなものをテンプレートにしているのですが、エラーは起きないのですが、うまく取得できません。

[code]

    #保存用
    driver_path = r'C:\Anaconda3\chromedriver.exe'#自分のChoromedriverの場所
    
    #読み込みたいフォルダの場所
    URL = 'https://nintei.nurse.or.jp/certification/General/(X(1)S(efl0y555pect3x45oxjzfw3x))/GCPP01LS/GCPP01LS.aspx'
    
    #格納したいフォルダの場所
    send_path = r'C:\Users\akira\Documents\Python\会社'
    
    from selenium import webdriver
    import time
    import bs4
    import re
    import os
    import time
    import shutil
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    start = time.time()
    
    driver = webdriver.Chrome(driver_path)
    driver.get(URL)
    time.sleep(3)
    
    soup = bs4.BeautifulSoup(driver.page_source, 'html5lib')
    
    base = 'https://nintei.nurse.or.jp/certification/General/'
    
    soup_file1 = soup.find_all('a')
    href_list = []
    
    file_num = 1
    sum_file = 1
    
    cc = 0
    for s in soup_file1:
        if s.string=='検索':
            path = base+s.get('href')
            href_list.append(path)
    
            print(path)
            driver.get(path)
    
            WebDriverWait(driver, 300).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="ctl00_plhContent_btnSearchMain"]')))
            driver.find_element_by_xpath('//*[@id="ctl00_plhContent_btnSearchMain"]').click()
    
            while sum_file == file_num :
                sum_file = len(os.listdir(r'C:\Users\akira\Downloads'))
    
            else:
                print("現在のダウンロードファイル数_{}枚".format(sum_file-1))
                file_num += 1
    
            cc += 1
    
    #一時ファイルが邪魔をする場合があるので時間を少し開ける
    time.sleep(60)
    
    #ファイルの移動
    dw_path = r'C:\Users\akira\Documents\Python\会社'
    dw_list = os.listdir(dw_path)
    
    dw_xlsx = [f for f in dw_list]
    for dw in dw_xlsx:
        shutil.move(r'C:\Users\akira\Documents\Python\会社')
    
[/code]


CC BY-SA 4.0
2020-07-28T13:57:50.250
69068
2021-02-24T04:03:20.407
2020-07-28T16:29:15.810
3060
41289
question
python python3 web-scraping
Pythonのスクレイピングでデータが取得できない


ウェブサイト上での情報の持ち方/見せ方は千差万別であり、同じような目的で同じ業者が作成しているとかならともかく、別々のサイトに適用できる
**テンプレート** と言えるようなものは存在しないでしょう。

何らかの **テンプレート** が存在する(適用できる)という考えは捨てて、対象サイトの内容/構成を調べる所から始めてください。

  * 該当のページでは、特に指定しない限り初期値では「全て」の情報を取得出来るようです。  
「認定看護師」「認定看護管理者」「専門看護師」の分類を指定して「検索」することで全てを取得出来るでしょう。

  * ただしそれぞれ1回の表示では50件だけですので、「次」ボタンをクリックして表示を進める必要があります。  
提示されたソースでは`a`タグのリストを取得してループし、その中で「検索」ボタンをクリックしていますが、それはこのページの内容に合っていません。

  * そのため、 **これら全てを一気に取得する方法** は **無い** でしょう。  
現時点で「認定看護師」は20721件登録されており、415ページ分ループが必要です。  
何らかの方法で1度に取得できる可能性はありますが、おそらくそれは非公開であり、継続して使用できるとは限らないでしょう。

参考：  
正規に全データが公開されている例：(Excelシートでダウンロード可)  
[情報処理安全確保支援士検索サービス](https://riss.ipa.go.jp/)

裏技でデータ取得出来る例：(コメントに裏技が紹介されている)  
[Python スクレイピング テーブル取得不可](https://ja.stackoverflow.com/q/66750/26370)  
スクレイピングによる取得の参考情報も私が回答しています。  
[seleniumでスクレイピング（次のページ対応）](https://imabari.hateblo.jp/entry/2020/03/05/215125)

* * *

考え方としては、以下のようになるでしょう。

  * `base = 'https://nintei.nurse.or.jp/certification/General/'`以後は全面的に見直す
  * 初回は`driver.find_element_by_xpath('//*[@id="ctl00_plhContent_btnSearchMain"]').click()`で取得
  * データはSeleniumかBeautifulSoupを使って`'//*[@id="ctl00_plhContent_dlvMain"]'`のXPathで取り出す(使いやすいと思う別の方法があればそれを使う)  
前後ページへのリンクや項目名等もテーブルに入っているので不要なら削っておく

  * 次ボタンクリックは`driver.find_element_by_xpath('//*[@id="page_navi_wrapper"]/ul/li[9]/a').click()`を使う
  * 最後まで表示してさらに次へ行こうとするとelementが無くて例外になるので、事前にelementの有無を確認するか、`try: except:`で例外検出してループを終了する


CC BY-SA 4.0
2020-07-29T01:20:16.043
69076
2020-07-29T01:25:36.963
2020-07-29T01:25:36.963
26370
26370
69068
answer


当該のページには幾つかの hidden parameter が埋め込まれています(例えば `__EVENTVALIDATION`
など)。最初のアクセスでこれらのパラメータの値を取得して、フォームデータの送信(submit)を行います。

以下はその処理を行なう python
スクリプトですが、レスポンス(HTMLファイル)には検索結果の最初の50件のみが含まれています。全ての検索結果を取得するためには、各ページへのリンクを辿ってHTMLファイルを取得する処理を追加する必要があります。

[code]

    import urllib
    from bs4 import BeautifulSoup
    
    # first access: get hidden parameters
    url = r'https://nintei.nurse.or.jp/certification/General/(X(1)S(efl0y555pect3x45oxjzfw3x))/General/GCPP01LS/GCPP01LS.aspx'
    html = urllib.request.urlopen(url)
    soup = BeautifulSoup(html, 'lxml')
    
    # generate form data
    count = int(soup.select('#__VIEWSTATEFIELDCOUNT')[0]['value'])
    form_data = {
      '__VIEWSTATEFIELDCOUNT': count,
      '__VIEWSTATE': soup.select('#__VIEWSTATE')[0]['value'],
      '__EVENTVALIDATION': soup.select('#__EVENTVALIDATION')[0]['value']
    }
    for i in range(1, count):
      form_data[f'__VIEWSTATE{i}'] = soup.select(f'#__VIEWSTATE{i}')[0]['value']
    
    form_data['ctl00$plhContent$btnSearchMain'] = '検索'
    form_data['ctl00$plhContent$drpField'] = -1
    form_data['ctl00$plhContent$drpNameOwnerWorking'] = -1
    form_data['ctl00$plhContent$drpWorkPrefecture'] = -1
    form_data['ctl00$plhContent$drpWorkType'] = -1
    form_data['ctl00$plhContent$radlstCert'] = 1
    
    # second access: get search result
    form_data = urllib.parse.urlencode(form_data).encode()
    html = urllib.request.urlopen(url, form_data).read().decode()
    print(html)
    
[/code]


CC BY-SA 4.0
2020-07-29T11:05:38.480
69098
2020-07-29T11:05:38.480
69068
answer