【问题标题】:Is there a way to create a loop logic that can select different option for each dropdown list and repeat it again for the next option?有没有办法创建一个循环逻辑,可以为每个下拉列表选择不同的选项并为下一个选项再次重复?
【发布时间】:2021-01-23 17:20:47
【问题描述】:

有谁知道如何在 Python 或 R 中使用 Selenium 在动态网页上自动抓取网页?

情况:
这个页面有几个下拉类别列表,每个类别列表都有几个选项,例如品牌是下拉类别列表之一,它有很多选项可供选择,例如 ALFA ROMEO、AUDI 等。其他类别列表也是如此。此外,要选择下一个类别列表的选项,必须首先选择上一个或第一个类别的选项。一旦选择了所有类别列表的选项,则下一阶段是单击“获取估值”按钮。它将输出给定表的信息。

目标:
目标是从表中获取所有选项的所有类别的所有信息,并将其存储为 .csv 格式。

屏幕截图 1(类别中的选项列表):


屏幕截图 2(输出):

问题:
我尝试创建一个逻辑,它可以单击每个类别并一次选择一个选项,然后继续选择下一个类别的选项。在流程结束时,它将单击提交按钮以获取评估信息。但是,如果给出了输入,我的脚本只能单击一个选项。然后,如果我想为所有类别选择下一个选项,我必须一遍又一遍地使用相同的脚本和不同的索引号输入(这指的是 id 的元素)。这将是一项乏味的非自动工作,如果有新更新的列表也可能成为问题。

要复制的代码示例:

import time
import requests
import pandas as pd
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver .support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

url = "https://www.carbase.my/tool/car-market-value-guide"
chrome_path = r"C:\Users\Noobie\Documents\utils\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
time.sleep(2)
driver.get(url)

def multi_define(driver, element_id, indexs):
    select = Select(driver.find_element_by_id(element_id))
    for index in indexs:
        select.select_by_index(index)

elem_cat = ('brand','family','year','cc','transmission','variant')

multi_define(driver, elem_cat[0], '2')
multi_define(driver, elem_cat[1], '2')
multi_define(driver, elem_cat[2], '2')
multi_define(driver, elem_cat[3], '2')
multi_define(driver, elem_cat[4], '1')
multi_define(driver, elem_cat[5], '1')
driver.find_element_by_id("loan-calculate").click()

输出: 参考截图2

你们能否建议如何创建一个可以循环并为每个下拉列表选择不同选项并为下一个选项再次重复的脚本?

【问题讨论】:

  • 您可以使用 rvest 包的 html_nodes(...) 函数来执行此操作。下拉列表中的每个项目都有一个 html“id”属性,它指向与该下拉项目关联的数据。我会使用 html_nodes(...) 函数来创建一个 id 列表,然后使用这些 id 来获取其余数据。看起来你很近。

标签: r python-3.x algorithm selenium web-scraping


【解决方案1】:

对于每个选择元素,让函数一个一个选择选项,然后在下一个选择元素上递归调用自己。

执行此操作时,您可以将当前选择的项目保存在一个数组中,当您到达最后一个选择项目时,您可以随意使用它们。这是您修改的代码,适用于您发布的 URL。

driver.get(url)

elem_cat = ('brand','family','year','cc','transmission','variant')

def multi_define(driver, elem_index, selected):
    select = Select(driver.find_element_by_id(elem_cat[elem_index]))
    options = select.options

    # select each option
    for i in range(1, len(options)):
        select.select_by_index(i)
        time.sleep(0.3)

        if elem_index == 5:
            # we are at the last select item
            driver.find_element_by_id("loan-calculate").click()
            selected = selected + [options[i].text]
            
            # clicked the button. selected options are in selected array.
            # do whatever you need to do with this information
            time.sleep(0.1)
            print(selected)

        elif options[i].text != "": # skip placeholders
            # recursive call for the next select. you can change [options[i].text]
            # to whatever information you need about this option
            multi_define(driver, elem_index + 1, selected + [options[i].text])

multi_define(driver, 0, [])

这段代码的输出:

['ALFA ROMEO', '145', '2001', '1598', '5 SP MANUAL']
['ALFA ROMEO', '145', '2000', '1598', '5 SP MANUAL']
['ALFA ROMEO', '145', '1999', '1598', '5 SP MANUAL']
['ALFA ROMEO', '145', '1998', '1598', '5 SP MANUAL']
['ALFA ROMEO', '145', '1997', '1598', '5 SP MANUAL']
['ALFA ROMEO', '145', '1996', '1598', '5 SP MANUAL']
['ALFA ROMEO', '145', '1995', '1598', '5 SP MANUAL']
['ALFA ROMEO', '145', '1995', '1598', '5 SP MANUAL']
['ALFA ROMEO', '146', '2002', '1598', '5 SP MANUAL']
...

【讨论】:

  • 这是我正在寻找的逻辑。它工作得很好。非常感谢我的朋友。
  • 对了,“multi_define(driver, 0, [])”是什么意思?最后一行代码。
  • multi_define 的第二个参数是我们当前所在的选择索引。最初我们从 0 开始。该函数在 select 0 中选择一个选项,并使用索引 1 调用自身。然后它将循环选择 1 中的选项(参见 elif 块中的 elem_index + 1)。最后一个参数是当前选定选项的数组。最初,我们没有选择任何东西。因此multi_define(driver, 0, [])。在每次选择时,函数都会在调用自身时将当前选项附加到数组:selected + [options[i].text]。我也添加了一行来附加最后一个选项,看起来我忘记了。
  • @Amz 多个脚本并行运行听起来不错。也许您应该找到一种方法,而不是增加 n2 直到除法为整数。因为如果你这样做,当 n1 是质数时,你将需要 n2 = n1 个脚本。
  • 关于如何识别哪些脚本从哪些选项开始会有一个问题 - 对。也许你的脚本需要作为一个参数,从哪个索引开始,在哪个索引停止。
猜你喜欢
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多