selenium + python 处理 select 标签下拉框的选项

1. 背景

  • 在爬取网页是,有时候我们会遇到下图中的下拉框,也就是 < select > < /select > 标签。按照一般的点击方案是无法成功的,而 selenium 提供了专门的 Select 类来处理这种下拉框。
    如下图:
    selenium + python 处理 select 标签下拉框的选项

2. select 下拉框的处理方案

  • 上图中的网页源代码如下:
<select aria-describedby="searchDropdownDescription" class="nav-search-dropdown searchSelect" data-nav-digest="tqOK4D0LUsrF1MzlVs7VjBv99ig=" data-nav-selected="0" id="searchDropdownBox" name="url" style="display: block; top: 0px;" tabindex="18" title="搜索范围">
        <option selected="selected" value="search-alias=aps">全部分类</option>
        <option value="search-alias=digital-text">Kindle商店</option>
        <option value="search-alias=digital-music">MP3 音乐</option>
        <option value="search-alias=instant-video">Prime Video</option>
        <option value="search-alias=stripbooks-intl-ship">图书</option>
        <option value="search-alias=baby-products-intl-ship">婴儿用品</option>
        <option value="search-alias=arts-crafts-intl-ship">工艺品</option>
        <option value="search-alias=automotive-intl-ship">汽车</option>
        <option value="search-alias=electronics-intl-ship">电子产品</option>
        <option value="search-alias=beauty-intl-ship">美容和个人护理</option>
        <option value="search-alias=computers-intl-ship">计算机</option>
        <option value="search-alias=fashion-womens-intl-ship">女士时尚</option>
        <option value="search-alias=fashion-mens-intl-ship">男士时尚</option>
        <option value="search-alias=fashion-girls-intl-ship">女童时尚</option>
        <option value="search-alias=fashion-boys-intl-ship">男童时尚</option>
        <option value="search-alias=hpc-intl-ship">健康和家居用品</option>
        <option value="search-alias=pets-intl-ship">宠物用品</option>
        <option value="search-alias=kitchen-intl-ship">家居厨房用品</option>
        <option value="search-alias=industrial-intl-ship">工业科技</option>
        <option value="search-alias=tools-intl-ship">工具与家居装饰</option>
        <option value="search-alias=movies-tv-intl-ship">影视</option>
        <option value="search-alias=toys-and-games-intl-ship">玩具与游戏</option>
        <option value="search-alias=luggage-intl-ship">行李箱包</option>
        <option value="search-alias=videogames-intl-ship">视频游戏</option>
        <option value="search-alias=software-intl-ship">软件</option>
        <option value="search-alias=sporting-intl-ship">运动与户外用品</option>
        <option value="search-alias=deals-intl-ship">销售和优惠</option>
        <option value="search-alias=music-intl-ship">音乐、CD和乙烯基塑料唱片</option>
</select>

可以看一下 selenium 源代码中 select.py 文件的实现:…\selenium\webdriver\support\select.py

2.1. 第一种方案:select_by_value

使用条件:用于选取 < option> 标签的 value 值,要求必须要有 value 属性,当然,这不是废话嘛…。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
import random
import time


browser = webdriver.Chrome()
browser.get("https://www.amazom.com/")

# 选中最后一个选项
# <option value="search-alias=music-intl-ship">音乐、CD和乙烯基塑料唱片</option>
classSelectValue = 'search-alias=music-intl-ship'
Select(browser.find_element_by_tag_name("select")).select_by_value(classSelectValue)

# 拿到搜索框
input = browser.find_element_by_xpath("//form[@name='site-search']/div[@class='nav-fill']//input[@class='nav-input']")

# 输入搜索关键字
time.sleep(random.randrange(1, 5, 1))
input.clear()
input.send_keys('CD')

# 敲enter键
input.send_keys(Keys.RETURN)

3.2. 第二种方案:select_by_index

  • 使用条件:要求下拉框的选项必须要有index 属性,例如 index=”1”。注意,这不是数组下标值,而是属性值!
# 稍微变一下,这种方法在这不合适,仅仅是mark一下 
Select(browser.find_element_by_tag_name("select")).select_by_index(2)

3.3. 第三种方案:select_by_visible_text

  • 使用条件:用于选取 < option> 标签的 text 值!
# <option value="search-alias=toys-and-games">Toys &amp; Games</option>
# 一定要注意是源代码中的text值,而不要从页面去复制,区别就在于,英文界面下的源代码中会有&amp
classSelectText = '软件'
Select(browser.find_element_by_tag_name("select")).select_by_visible_text(classSelectText )