

Python3.10.2とseleniumを使用しています。

商品コードを入力、表示された在庫数をスクレイピングしてCSVに保存、という流れなのですが、商品数が増えてきたので、ループ処理に変更したく思っています。

ループしたい処理は下記になります。  
send_data(n)を1～4000ぐらいまで増やしていく処理ができないか考えています。  
なおsend_dataには商品のコードが事前に格納されています。

ご教示のほどよろしくお願いいたします。

[code]

    driver.find_element_by_name("ban01").send_keys(send_data1)
    driver.find_element_by_name("ban02").send_keys(send_data2)
    driver.find_element_by_name("ban03").send_keys(send_data3)
    driver.find_element_by_name("ban11").send_keys(send_data4)
    driver.find_element_by_name("ban12").send_keys(send_data5)
    driver.find_element_by_name("ban13").send_keys(send_data6)
    driver.find_element_by_name("ban21").send_keys(send_data7)
    driver.find_element_by_name("ban22").send_keys(send_data8)
    driver.find_element_by_name("ban23").send_keys(send_data9)
    driver.find_element_by_name("ban31").send_keys(send_data10)
    driver.find_element_by_name("ban32").send_keys(send_data11)
    driver.find_element_by_name("ban33").send_keys(send_data12)
    driver.find_element_by_name("ban41").send_keys(send_data13)
    driver.find_element_by_name("ban42").send_keys(send_data14)
    driver.find_element_by_name("ban43").send_keys(send_data15)
    driver.find_element_by_name("ban51").send_keys(send_data16)
    driver.find_element_by_name("ban52").send_keys(send_data17)
    driver.find_element_by_name("ban53").send_keys(send_data18)
    driver.find_element_by_name("ban61").send_keys(send_data19)
    driver.find_element_by_name("ban62").send_keys(send_data20)
    driver.find_element_by_name("ban63").send_keys(send_data21)
    driver.find_element_by_name("ban71").send_keys(send_data22)
    driver.find_element_by_name("ban72").send_keys(send_data23)
    driver.find_element_by_name("ban73").send_keys(send_data24)
    driver.find_element_by_name("ban81").send_keys(send_data25)
    driver.find_element_by_name("ban82").send_keys(send_data26)
    driver.find_element_by_name("ban83").send_keys(send_data27)
    driver.find_element_by_name("ban91").send_keys(send_data28)
    driver.find_element_by_name("ban92").send_keys(send_data29)
    driver.find_element_by_name("ban93").send_keys(send_data30)
    
    time.sleep(3)
    driver.find_element_by_xpath("送信ボタンのxpath").click()
    time.sleep(3)
                                                              
    list0 =[driver.find_element_by_xpath("商品名0").text, driver.find_element_by_xpath("商品名0の在庫数").text,send_data1,send_data2,send_data3]
    list1 =[driver.find_element_by_xpath("商品名1").text, driver.find_element_by_xpath("商品名1の在庫数").text,send_data4,send_data5,send_data6]
    list2 =[driver.find_element_by_xpath("商品名2").text, driver.find_element_by_xpath("商品名2の在庫数").text,send_data7,send_data8,send_data9]
    list3 =[driver.find_element_by_xpath("商品名3").text, driver.find_element_by_xpath("商品名3の在庫数").text,send_data10,send_data11,send_data12]
    list4 =[driver.find_element_by_xpath("商品名4").text, driver.find_element_by_xpath("商品名4の在庫数").text,send_data13,send_data14,send_data15]
    list5 =[driver.find_element_by_xpath("商品名5").text, driver.find_element_by_xpath("商品名5の在庫数").text,send_data16,send_data17,send_data18]
    list6 =[driver.find_element_by_xpath("商品名6").text, driver.find_element_by_xpath("商品名6の在庫数").text,send_data19,send_data20,send_data21]
    list7 =[driver.find_element_by_xpath("商品名7").text, driver.find_element_by_xpath("商品名7の在庫数").text,send_data22,send_data23,send_data24]
    list8 =[driver.find_element_by_xpath("商品名8").text, driver.find_element_by_xpath("商品名8の在庫数").text,send_data25,send_data26,send_data27]
    list9 =[driver.find_element_by_xpath("商品名9").text, driver.find_element_by_xpath("商品名9の在庫数").text,send_data28,send_data29,send_data30]
    with open(r "CSVのパス\zaiko.csv",'a', encoding="shift-jis", newline='') as f:
        writer = csv.writer(f, lineterminator='\n') 
        writer.writerow(list0)
        writer.writerow(list1)
        writer.writerow(list2)
        writer.writerow(list3)
        writer.writerow(list4)
        writer.writerow(list5)
        writer.writerow(list6)
        writer.writerow(list7)
        writer.writerow(list8)
        writer.writerow(list9)
    
[/code]

以下は解決済。ありがとうございます。

* * *

コメントにて返信しましたが、わかりにくかったのでこちらにも追記いたします。  
いただいたものを組み込むと以下のエラーとなりました。

[code]

    >>> max = 10#任意の最大値
    >>> n = 1
    >>> while n<max :
    ...   n += 1
    ...
    ... driver.find_element_by_name("ban01").send_keys(exec("send_data"+str(n)))
      File "<stdin>", line 4
        driver.find_element_by_name("ban01").send_keys(exec("send_data"+str(n)))
        ^^^^^^
    SyntaxError: invalid syntax
    
[/code]

以前にもselenium内で演算などを行うとinvalid syntaxが出た覚えがあります。  
当時もdriverに指摘が入っているのがよくわからなった記憶です。  
ご教示のほどよろしくお願いいたします

* * *

現在は以下のエラーと格闘中です。  
TypeError: object of type 'NoneType' has no len()

[code]

    >>> MNum = 10
    >>> n = 1
    >>> while n < MNum :
    ...   n += 1
    ...
    ...   driver.find_element_by_name("ban01").send_keys(exec("send_data"+str(n)))
    
    略
    
    TypeError: object of type 'NoneType' has no len()
    
[/code]

* * *

さまざまなご提案ありがとうございます。  
この問題をややこしくしている、いくつかの情報を追加いたします。

[![商品コード入力＆検索結果が帰ってくる画面](https://i.stack.imgur.com/VBQHw.png)](https://i.stack.imgur.com/VBQHw.png)

1）ひとつの商品につき、商品コードを3つに分けて入力する仕様になっています。banXXのx1, x2, x3はその並びを意味します。

[![ソースのキャプチャ](https://i.stack.imgur.com/qbnGE.png)](https://i.stack.imgur.com/qbnGE.png)

2)一度に検索できる上限がban0x～ban9xまでの10個になります。

3)ここには記載がありませんが、ID＆PWによるログイン、およびランダム時間でタイムアウトがあり、再ログインの処理があります。


CC BY-SA 4.0
2022-10-24T09:47:05.170
91789
2022-10-26T05:27:21.907
2022-10-26T02:53:24.727
55002
55002
question
python python3 selenium
Pythonにて、引数をループ処理で増やしていく事はできますか？


send_dataの部分のみ抜粋させていただきました。使う際はprint()内を移してexec()などを使ってください。

[code]

    NumMax = 10#任意の最大値
    n = 0
    while n<NumMax :
      n += 1
      print("send_data"+str(n))
      print("send_data"+str(3*n-2)+",send_data"+str(3*n-1)+",sand_data"+str(3*n))
    
[/code]

上の文のsend_dataについては

[code]

    +#文字列及び数値結合
    
[/code]

と

[code]

    str()#str型に変換(この場合はnをint型からstr型へ)
    
[/code]

を用いてくっつけてあげることで実現し、下のSend_dataでは上記のことに加えnを3倍した数から一定の数を引いてあげることで実現しています。

わかりにくい説明失礼しました。

* * *

10/25 16:46追記

[code]

    TypeError: object of type 'NoneType' has no len()
    
[/code]

とのエラーが発生しているとのことですが以下の方法で解決するかもしれません。(コメントで同様の内容を投稿させていただきましたが、より見やすくさせていただきたいと思い追記しました。)  
調べてみた所「exec()には戻り値がないため、exec()自体は存在しない」とのことでした。戻り値がNoneなので上記のエラーが発生していると思われます。私もあまり詳しくはないのですが、以下のように文全体を囲んであげることで解決できないでしょうか？

[code]

    exec('driver.find_element_by_name("ban01").send_keys("send_data"+str(n))')
    
[/code]

* * *

18:28追記  
上のコードでは動作しなかったそうです。  
ご迷惑をおかけしました。


CC BY-SA 4.0
2022-10-24T10:37:40.683
91790
2022-10-25T09:29:07.337
2022-10-25T09:29:07.337
54864
54864
91789
answer


**追加情報を基に全面改訂：**

例えば検索用の3つの情報の組み合わせを`型番,枝番,詳細`といった形でCSVファイルに用意しておき、それを読み込んで処理するという方法が考えられます。  
検索用CSVファイル(SearchItems.csv)データ例：

[code]

    型番,枝番,詳細
    49123,456789,01
    49123,457890,12
    49123,458901,23
    ...以下情報が続く
    
[/code]

上記を`csv`モジュールで辞書データとして読み込めば、後の処理はループの組み合わせで簡単になるでしょう。  
結果のCSVファイル出力も`csv`モジュールで辞書データとして出力すれば良いでしょう。  
以下のような形が考えられます。例外処理等は必要に応じて入れてください。  
ファイル名は簡略化のために決め打ちですが、コマンドラインパラメータで変えられるようにしておくのも良いでしょう。

[code]

    import csv
    
    with open('SearchItems.csv', 'r', encoding='cp932', newline='') as f:
        reader = csv.DictReader(f)
        ItemCodeList = [row for row in reader]
    
    ItemAmount = len(ItemCodeList)
    MaxPageItems = 10
    
    ResultHeader = ['商品名', '在庫数', '型番', '枝番', '詳細']
    
    for base in range(0, ItemAmount, MaxPageItems):
        PageItems = ItemCodeList[base:(base + MaxPageItems)]
        PageRows = len(PageItems)
        for n in range(PageRows):
            driver.find_element_by_name(f'ban{n}1').send_keys(PageItems[n][ResultHeader[2]])
            driver.find_element_by_name(f'ban{n}2').send_keys(PageItems[n][ResultHeader[3]])
            driver.find_element_by_name(f'ban{n}3').send_keys(PageItems[n][ResultHeader[4]])
        
        time.sleep(3)
        driver.find_element_by_xpath("送信ボタンのxpath").click()
        time.sleep(3)
        
        PageInventory = []
        for m in range(PageRows):
            ItemInventory = {ResultHeader[0]:driver.find_element_by_xpath(f'商品名{m}').text}
            ItemInventory |= {ResultHeader[1]:driver.find_element_by_xpath(f'商品名{m}の在庫数').text}
            ItemInventory |= PageItems[m]
            PageInventory.append(ItemInventory)
        
        with open(r'CSVのパス\zaiko.csv', 'a', encoding='cp932', newline='') as f:
            writer = csv.DictWriter(f, fieldnames=ResultHeader, lineterminator='\n')
            if f.tell() <= 0:
                writer.writeheader()
            writer.writerows(PageInventory)
        
        #### 複数回にわたる問い合わせ時に、前回の情報をいったんクリアする機能が検索画面に必要と思われる
        time.sleep(3)
        driver.find_element_by_xpath("データクリアボタンのxpath").click()
        time.sleep(3)
    
[/code]


CC BY-SA 4.0
2022-10-25T11:40:18.793
91813
2022-10-26T05:27:21.907
2022-10-26T05:27:21.907
26370
26370
91789
answer