Python Selenium 從零開(kāi)始掌握瀏覽器自動(dòng)化(超詳細(xì)新手教程)
一、寫(xiě)給新手的話
如果你是第一次接觸Selenium,可能會(huì)覺(jué)得有些復(fù)雜。別擔(dān)心!這篇教程將從最基礎(chǔ)的安裝開(kāi)始,一步步帶你掌握Selenium的每個(gè)細(xì)節(jié)。我會(huì)用最簡(jiǎn)單的語(yǔ)言和大量示例代碼,讓你快速上手。
二、準(zhǔn)備工作:環(huán)境搭建
2.1 安裝Python(如果你還沒(méi)有)
首先確認(rèn)你安裝了Python。打開(kāi)命令行(Windows按Win+R,輸入cmd;Mac打開(kāi)終端),輸入:
python --version
如果看到類(lèi)似 Python 3.12.7 這樣的版本號(hào),說(shuō)明已安裝。如果沒(méi)有,去Python官網(wǎng)下載安裝。
2.2 安裝Selenium庫(kù)
在命令行中輸入:
pip install selenium
如果下載慢,可以使用國(guó)內(nèi)鏡像:
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
2.3 安裝瀏覽器驅(qū)動(dòng)管理工具
傳統(tǒng)方式需要手動(dòng)下載瀏覽器驅(qū)動(dòng),但現(xiàn)在有更簡(jiǎn)單的方法:
pip install webdriver-manager
這個(gè)工具會(huì)自動(dòng)幫你下載和配置瀏覽器驅(qū)動(dòng)。
三、第一個(gè)Selenium程序:打開(kāi)百度
讓我們從一個(gè)最簡(jiǎn)單的例子開(kāi)始:
# 1. 導(dǎo)入必要的庫(kù)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
# 2. 自動(dòng)下載并設(shè)置Chrome驅(qū)動(dòng)
service = Service(ChromeDriverManager().install())
# 3. 創(chuàng)建瀏覽器對(duì)象(會(huì)彈出一個(gè)Chrome窗口)
driver = webdriver.Chrome(service=service)
# 4. 打開(kāi)百度首頁(yè)
driver.get("https://www.baidu.com")
# 5. 等待5秒,讓你看到效果
import time
time.sleep(5)
# 6. 關(guān)閉瀏覽器
driver.quit()運(yùn)行這個(gè)程序,你會(huì)看到:
- 自動(dòng)打開(kāi)Chrome瀏覽器
- 自動(dòng)訪問(wèn)百度首頁(yè)
- 5秒后自動(dòng)關(guān)閉
四、Selenium基礎(chǔ)操作詳解
4.1 常用操作匯總表
| 操作 | 方法 | 示例 |
|---|---|---|
| 打開(kāi)網(wǎng)頁(yè) | driver.get(url) | driver.get("https://www.baidu.com") |
| 獲取頁(yè)面標(biāo)題 | driver.title | title = driver.title |
| 獲取當(dāng)前URL | driver.current_url | url = driver.current_url |
| 前進(jìn) | driver.forward() | driver.forward() |
| 后退 | driver.back() | driver.back() |
| 刷新 | driver.refresh() | driver.refresh() |
| 關(guān)閉當(dāng)前窗口 | driver.close() | driver.close() |
| 關(guān)閉所有窗口 | driver.quit() | driver.quit() |
| 最大化窗口 | driver.maximize_window() | driver.maximize_window() |
| 設(shè)置窗口大小 | driver.set_window_size(width, height) | driver.set_window_size(800, 600) |
4.2 詳細(xì)操作示例
# 基礎(chǔ)操作示例代碼
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time
# 初始化瀏覽器
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# 訪問(wèn)第一個(gè)網(wǎng)站
driver.get("https://www.baidu.com")
print(f"當(dāng)前頁(yè)面標(biāo)題:{driver.title}")
print(f"當(dāng)前頁(yè)面URL:{driver.current_url}")
# 等待2秒
time.sleep(2)
# 訪問(wèn)第二個(gè)網(wǎng)站
driver.get("https://www.taobao.com")
print(f"新頁(yè)面標(biāo)題:{driver.title}")
# 等待2秒
time.sleep(2)
# 后退到百度
driver.back()
print(f"后退后頁(yè)面:{driver.title}")
# 等待2秒
time.sleep(2)
# 前進(jìn)到淘寶
driver.forward()
print(f"前進(jìn)后頁(yè)面:{driver.title}")
# 刷新頁(yè)面
driver.refresh()
# 最大化窗口
driver.maximize_window()
# 設(shè)置窗口大小
driver.set_window_size(800, 600)
finally:
# 關(guān)閉瀏覽器
time.sleep(3)
driver.quit()
print("瀏覽器已關(guān)閉")五、元素定位:找到網(wǎng)頁(yè)上的內(nèi)容
這是Selenium最重要的部分!就像在網(wǎng)頁(yè)上找東西一樣,我們需要告訴Selenium"我要找什么"。
5.1 8種定位方式(從易到難)
方式1:通過(guò)ID定位(最簡(jiǎn)單)
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
# HTML元素有id屬性時(shí)使用(id通常是唯一的)
search_input = driver.find_element("id", "kw")
# 或者
search_input = driver.find_element_by_id("kw")方式2:通過(guò)NAME定位
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
python
# name屬性可能不唯一,但經(jīng)常使用
search_input = driver.find_element("name", "wd")
# 或者
search_input = driver.find_element_by_name("wd")方式3:通過(guò)CLASS_NAME定位
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
# class可能不唯一,一個(gè)元素可能有多個(gè)class
search_input = driver.find_element("class name", "s_ipt")
# 或者
search_input = driver.find_element_by_class_name("s_ipt")方式4:通過(guò)TAG_NAME定位
<div>內(nèi)容</div> <input type="text"> <a href="..." rel="external nofollow" >鏈接</a>
# 通過(guò)標(biāo)簽名查找(最不精確,通常用來(lái)查找多個(gè)元素)
divs = driver.find_elements("tag name", "div") # 所有div元素
inputs = driver.find_elements("tag name", "input") # 所有input元素
links = driver.find_elements("tag name", "a") # 所有鏈接方式5:通過(guò)LINK_TEXT定位
<a rel="external nofollow" rel="external nofollow" >新聞</a> <a rel="external nofollow" rel="external nofollow" >hao123</a>
# 精確匹配鏈接文本
news_link = driver.find_element("link text", "新聞")
hao123_link = driver.find_element("link text", "hao123")方式6:通過(guò)PARTIAL_LINK_TEXT定位
<a rel="external nofollow" rel="external nofollow" >百度新聞</a> <a rel="external nofollow" rel="external nofollow" >hao123網(wǎng)址導(dǎo)航</a>
# 部分匹配鏈接文本(包含即可)
baidu_link = driver.find_element("partial link text", "百度") # 匹配"百度新聞"
hao123_link = driver.find_element("partial link text", "hao123") # 匹配"hao123網(wǎng)址導(dǎo)航"方式7:通過(guò)CSS_SELECTOR定位(推薦)
CSS選擇器功能強(qiáng)大,類(lèi)似于CSS樣式選擇元素:
# 通過(guò)id
element = driver.find_element("css selector", "#kw") # #表示id
# 通過(guò)class
element = driver.find_element("css selector", ".s_ipt") # .表示class
# 通過(guò)標(biāo)簽名+class
element = driver.find_element("css selector", "input.s_ipt") # input標(biāo)簽且class為s_ipt
# 通過(guò)屬性
element = driver.find_element("css selector", "[name='wd']") # name屬性為wd
# 組合選擇
element = driver.find_element("css selector", "input#kw.s_ipt[name='wd']")方式8:通過(guò)XPATH定位(最強(qiáng)大)
XPath就像文件路徑,可以定位到任何元素:
# 絕對(duì)路徑(從html開(kāi)始)
element = driver.find_element("xpath", "/html/body/div/div[2]/div/div/div/form/span/input")
# 相對(duì)路徑(推薦)
element = driver.find_element("xpath", "http://input") # 所有input標(biāo)簽
# 帶屬性的相對(duì)路徑
element = driver.find_element("xpath", "http://input[@id='kw']") # id為kw的input
element = driver.find_element("xpath", "http://input[@name='wd']") # name為wd的input
# 使用and/or
element = driver.find_element("xpath", "http://input[@id='kw' and @name='wd']")
# 使用文本內(nèi)容
element = driver.find_element("xpath", "http://a[text()='新聞']") # 文本為"新聞"的鏈接
element = driver.find_element("xpath", "http://a[contains(text(),'新聞')]") # 包含"新聞"的鏈接5.2 元素定位完整示例
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
# 初始化瀏覽器
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# 打開(kāi)百度
driver.get("https://www.baidu.com")
# 各種定位方式的示例
# 1. 通過(guò)ID定位搜索框
search_box = driver.find_element(By.ID, "kw")
# 2. 通過(guò)NAME定位搜索框
search_box = driver.find_element(By.NAME, "wd")
# 3. 通過(guò)CLASS_NAME定位搜索框
search_box = driver.find_element(By.CLASS_NAME, "s_ipt")
# 4. 通過(guò)TAG_NAME定位所有輸入框
inputs = driver.find_elements(By.TAG_NAME, "input")
print(f"找到 {len(inputs)} 個(gè)input元素")
# 5. 通過(guò)LINK_TEXT定位"新聞"鏈接
news_link = driver.find_element(By.LINK_TEXT, "新聞")
# 6. 通過(guò)PARTIAL_LINK_TEXT定位包含"新"的鏈接
news_links = driver.find_elements(By.PARTIAL_LINK_TEXT, "新")
print(f"找到 {len(news_links)} 個(gè)包含'新'的鏈接")
# 7. 通過(guò)CSS_SELECTOR定位
search_box = driver.find_element(By.CSS_SELECTOR, "#kw") # id選擇器
search_box = driver.find_element(By.CSS_SELECTOR, ".s_ipt") # class選擇器
search_box = driver.find_element(By.CSS_SELECTOR, "input#kw") # 標(biāo)簽+id
# 8. 通過(guò)XPATH定位
search_box = driver.find_element(By.XPATH, "http://input[@id='kw']")
search_box = driver.find_element(By.XPATH, "http://*[@id='kw']")
print("所有定位方式測(cè)試成功!")
finally:
driver.quit()5.3 元素定位選擇建議
| 場(chǎng)景 | 推薦方式 | 原因 |
|---|---|---|
| 元素有id | By.ID | 最簡(jiǎn)單、最快、唯一 |
| 元素有name | By.NAME | 簡(jiǎn)單常用 |
| 元素有class | By.CLASS_NAME | 簡(jiǎn)單,但class可能重復(fù) |
| 查找多個(gè)同類(lèi)元素 | By.TAG_NAME | 查找所有同類(lèi)元素 |
| 精確文本鏈接 | By.LINK_TEXT | 鏈接文本不變時(shí)使用 |
| 模糊文本鏈接 | By.PARTIAL_LINK_TEXT | 鏈接文本部分匹配 |
| 復(fù)雜選擇 | By.CSS_SELECTOR | 功能強(qiáng)大,語(yǔ)法簡(jiǎn)潔 |
| 最復(fù)雜情況 | By.XPATH | 功能最強(qiáng)大,但稍慢 |
六、元素操作:與網(wǎng)頁(yè)交互
找到元素后,我們需要與之交互。下面是常用的操作:
6.1 輸入文本
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
driver.get("https://www.baidu.com")
# 找到搜索框
search_box = driver.find_element(By.ID, "kw")
# 方法1:直接輸入
search_box.send_keys("Python教程")
time.sleep(2)
# 方法2:先清空再輸入
search_box.clear() # 清空內(nèi)容
search_box.send_keys("Selenium教程")
time.sleep(2)
# 方法3:輸入特殊鍵(如回車(chē))
from selenium.webdriver.common.keys import Keys
search_box.clear()
search_box.send_keys("自動(dòng)化測(cè)試")
search_box.send_keys(Keys.ENTER) # 按回車(chē)鍵
time.sleep(2)
finally:
driver.quit()6.2 點(diǎn)擊操作
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
driver.get("https://www.baidu.com")
# 找到搜索框并輸入內(nèi)容
search_box = driver.find_element(By.ID, "kw")
search_box.send_keys("Python")
# 方法1:直接點(diǎn)擊百度一下按鈕
search_button = driver.find_element(By.ID, "su")
search_button.click()
time.sleep(2)
# 方法2:模擬鍵盤(pán)回車(chē)(不需要點(diǎn)擊按鈕)
driver.back() # 返回百度首頁(yè)
time.sleep(1)
search_box = driver.find_element(By.ID, "kw")
search_box.clear()
search_box.send_keys("Selenium")
search_box.submit() # 提交表單(相當(dāng)于在輸入框按回車(chē))
time.sleep(2)
finally:
driver.quit()6.3 獲取元素信息
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
driver.get("https://www.baidu.com")
# 獲取搜索框元素
search_box = driver.find_element(By.ID, "kw")
# 獲取元素的各種屬性
print(f"元素標(biāo)簽名: {search_box.tag_name}")
print(f"元素ID: {search_box.get_attribute('id')}")
print(f"元素name: {search_box.get_attribute('name')}")
print(f"元素class: {search_box.get_attribute('class')}")
print(f"元素類(lèi)型: {search_box.get_attribute('type')}")
print(f"元素值: {search_box.get_attribute('value')}")
print(f"元素是否可見(jiàn): {search_box.is_displayed()}")
print(f"元素是否可用: {search_box.is_enabled()}")
print(f"元素是否被選中: {search_box.is_selected()}")
# 獲取元素位置和大小
location = search_box.location
size = search_box.size
print(f"元素位置: x={location['x']}, y={location['y']}")
print(f"元素大小: 寬={size['width']}, 高={size['height']}")
# 獲取元素文本(對(duì)于有文本的元素)
baidu_link = driver.find_element(By.LINK_TEXT, "百度首頁(yè)")
print(f"鏈接文本: {baidu_link.text}")
finally:
driver.quit()6.4 處理下拉框
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
import time
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# 訪問(wèn)一個(gè)測(cè)試頁(yè)面(包含下拉框)
driver.get("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select")
# 切換到iframe(因?yàn)檫@個(gè)頁(yè)面有iframe框架)
driver.switch_to.frame("iframeResult")
# 找到下拉框
cars_select = driver.find_element(By.ID, "cars")
# 創(chuàng)建Select對(duì)象
select = Select(cars_select)
# 方法1:通過(guò)可見(jiàn)文本選擇
select.select_by_visible_text("Audi")
time.sleep(1)
# 方法2:通過(guò)value值選擇
select.select_by_value("opel")
time.sleep(1)
# 方法3:通過(guò)索引選擇(從0開(kāi)始)
select.select_by_index(0) # 選擇第一個(gè)選項(xiàng)
time.sleep(1)
# 獲取所有選項(xiàng)
all_options = select.options
print("所有選項(xiàng):")
for option in all_options:
print(f" {option.text} (value: {option.get_attribute('value')})")
# 獲取已選中的選項(xiàng)
selected_option = select.first_selected_option
print(f"當(dāng)前選中: {selected_option.text}")
finally:
driver.quit()6.5 處理復(fù)選框和單選框
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# 訪問(wèn)測(cè)試頁(yè)面
driver.get("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_type_checkbox")
# 切換到iframe
driver.switch_to.frame("iframeResult")
# 找到復(fù)選框
vehicle1 = driver.find_element(By.ID, "vehicle1") # 自行車(chē)
vehicle2 = driver.find_element(By.ID, "vehicle2") # 汽車(chē)
vehicle3 = driver.find_element(By.ID, "vehicle3") # 船
# 檢查復(fù)選框狀態(tài)
print(f"自行車(chē)是否選中: {vehicle1.is_selected()}")
print(f"汽車(chē)是否選中: {vehicle2.is_selected()}")
print(f"船是否選中: {vehicle3.is_selected()}")
# 選中復(fù)選框(如果未選中)
if not vehicle1.is_selected():
vehicle1.click()
time.sleep(1)
if not vehicle2.is_selected():
vehicle2.click()
time.sleep(1)
# 取消選中(如果已選中)
if vehicle3.is_selected():
vehicle3.click()
time.sleep(1)
# 重新檢查狀態(tài)
print(f"自行車(chē)是否選中: {vehicle1.is_selected()}")
print(f"汽車(chē)是否選中: {vehicle2.is_selected()}")
print(f"船是否選中: {vehicle3.is_selected()}")
finally:
driver.quit()七、等待機(jī)制:讓程序"等一等"
網(wǎng)頁(yè)加載需要時(shí)間,我們需要等待元素出現(xiàn)后再操作。
7.1 強(qiáng)制等待(不推薦)
import time time.sleep(5) # 強(qiáng)制等待5秒,不管元素是否加載完成
缺點(diǎn):如果元素提前加載完成,也要等;如果超時(shí)未加載,會(huì)報(bào)錯(cuò)。
7.2 隱式等待(全局等待)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
# 設(shè)置隱式等待10秒
driver.implicitly_wait(10)
# 之后的所有find_element操作都會(huì)最多等待10秒
driver.get("https://www.baidu.com")
element = driver.find_element("id", "kw") # 最多等10秒優(yōu)點(diǎn):設(shè)置一次,全局生效。
7.3 顯式等待(推薦)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
driver.get("https://www.baidu.com")
# 創(chuàng)建等待對(duì)象(最多等10秒,每0.5秒檢查一次)
wait = WebDriverWait(driver, 10, 0.5)
# 等待元素出現(xiàn)
search_box = wait.until(
EC.presence_of_element_located((By.ID, "kw"))
)
print("搜索框已出現(xiàn)")
# 等待元素可點(diǎn)擊
search_button = wait.until(
EC.element_to_be_clickable((By.ID, "su"))
)
print("搜索按鈕可點(diǎn)擊")
# 等待元素可見(jiàn)
logo = wait.until(
EC.visibility_of_element_located((By.ID, "lg"))
)
print("百度logo可見(jiàn)")
# 等待文本出現(xiàn)在元素中
news_link = wait.until(
EC.text_to_be_present_in_element((By.LINK_TEXT, "新聞"), "新聞")
)
print("新聞鏈接文本正確")
finally:
driver.quit()7.4 常用等待條件
| 條件 | 說(shuō)明 |
|---|---|
presence_of_element_located | 元素出現(xiàn)在DOM中(不一定可見(jiàn)) |
visibility_of_element_located | 元素可見(jiàn)(有寬高,非隱藏) |
element_to_be_clickable | 元素可點(diǎn)擊 |
text_to_be_present_in_element | 元素包含特定文本 |
title_contains | 頁(yè)面標(biāo)題包含特定文本 |
alert_is_present | 出現(xiàn)警告框 |
7.5 等待機(jī)制完整示例
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# 1. 設(shè)置隱式等待
driver.implicitly_wait(5)
# 2. 訪問(wèn)慢速網(wǎng)站測(cè)試等待
driver.get("https://the-internet.herokuapp.com/dynamic_loading/2")
# 3. 點(diǎn)擊開(kāi)始按鈕
start_button = driver.find_element(By.XPATH, "http://button[text()='Start']")
start_button.click()
# 4. 創(chuàng)建顯式等待對(duì)象
wait = WebDriverWait(driver, 10)
# 5. 等待加載完成文字出現(xiàn)
finish_text = wait.until(
EC.visibility_of_element_located((By.ID, "finish"))
)
print(f"加載完成,文字內(nèi)容: {finish_text.text}")
# 6. 等待特定文本出現(xiàn)
wait.until(
EC.text_to_be_present_in_element((By.ID, "finish"), "Hello World!")
)
print("成功等到'Hello World!'文本")
finally:
time.sleep(2)
driver.quit()八、綜合實(shí)戰(zhàn):自動(dòng)化登錄并爬取數(shù)據(jù)
現(xiàn)在我們來(lái)完成一個(gè)完整的實(shí)戰(zhàn)案例:登錄并爬取Bing圖片的描述信息。
8.1 項(xiàng)目目標(biāo)
- 訪問(wèn)Bing圖片搜索
- 搜索"
小黑子"圖片 - 滾動(dòng)加載更多圖片
- 獲取每張圖片的標(biāo)題和描述
- 保存數(shù)據(jù)到文件
8.2 完整代碼(帶詳細(xì)注釋?zhuān)?/h3>
"""
Bing圖片爬蟲(chóng) - Selenium新手實(shí)戰(zhàn)教程
功能:自動(dòng)搜索并獲取Bing圖片信息
"""
# 導(dǎo)入所需庫(kù)
import os
import time
import json
import csv
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
class BingImageCrawler:
"""Bing圖片爬蟲(chóng)類(lèi)"""
def __init__(self, headless=False):
"""
初始化爬蟲(chóng)
參數(shù):
headless: 是否使用無(wú)頭模式(不顯示瀏覽器窗口)
默認(rèn)False顯示窗口,適合新手調(diào)試
"""
print("=" * 50)
print("Bing圖片爬蟲(chóng) - 初始化中...")
print("=" * 50)
# 創(chuàng)建保存數(shù)據(jù)的文件夾
self.data_dir = "bing_images_data"
if not os.path.exists(self.data_dir):
os.makedirs(self.data_dir)
print(f"創(chuàng)建文件夾: {self.data_dir}")
# 設(shè)置瀏覽器選項(xiàng)
options = webdriver.ChromeOptions()
# 如果設(shè)置為無(wú)頭模式,不顯示瀏覽器窗口
if headless:
options.add_argument('--headless')
print("啟用無(wú)頭模式(不顯示瀏覽器窗口)")
# 其他配置
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1920,580') # 設(shè)置窗口大小
# 使用DriverManager自動(dòng)管理瀏覽器驅(qū)動(dòng)
print("正在下載/配置Chrome瀏覽器驅(qū)動(dòng)...")
service = Service(ChromeDriverManager().install())
# 啟動(dòng)瀏覽器
self.driver = webdriver.Chrome(service=service, options=options)
# 設(shè)置等待時(shí)間
self.wait = WebDriverWait(self.driver, 5)
print("瀏覽器啟動(dòng)成功!")
def search_images(self, keyword, max_images=10):
"""
搜索圖片
參數(shù):
keyword: 搜索關(guān)鍵詞,如"小黑子"
max_images: 最大圖片數(shù)量
返回:
圖片數(shù)據(jù)列表
"""
print(f"\n開(kāi)始搜索: {keyword}")
try:
# 1. 訪問(wèn)Bing圖片搜索
search_url = f"https://cn.bing.com/images/search?q={keyword}"
self.driver.get(search_url)
print(f"訪問(wèn)URL: {search_url}")
# 等待頁(yè)面加載
time.sleep(2)
# 2. 等待搜索框出現(xiàn)(確認(rèn)頁(yè)面加載完成)
try:
search_box = self.wait.until(
EC.presence_of_element_located((By.ID, "sb_form_q"))
)
print("頁(yè)面加載完成")
except:
print("頁(yè)面加載異常,但繼續(xù)執(zhí)行...")
# 3. 滾動(dòng)加載更多圖片
print("開(kāi)始滾動(dòng)加載圖片...")
loaded_count = self._scroll_to_load_images(max_images)
# 4. 獲取圖片數(shù)據(jù)
print("開(kāi)始解析圖片信息...")
images_data = self._parse_images(loaded_count)
if images_data:
print(f"成功獲取 {len(images_data)} 張圖片信息")
else:
print("未找到圖片數(shù)據(jù)")
return images_data
except Exception as e:
print(f"搜索過(guò)程中發(fā)生錯(cuò)誤: {str(e)}")
return []
def _scroll_to_load_images(self, max_images):
"""
滾動(dòng)頁(yè)面加載更多圖片
返回:
加載的圖片數(shù)量
"""
images_count = 0
scroll_count = 0
max_scroll = 1 # 最大滾動(dòng)次數(shù)
while images_count < max_images and scroll_count < max_scroll:
# 獲取當(dāng)前圖片數(shù)量
current_images = self.driver.find_elements(
By.CSS_SELECTOR, '.imgpt .iusc'
)
images_count = len(current_images)
print(f" 已加載 {images_count} 張圖片")
# 如果已達(dá)到目標(biāo)數(shù)量,停止?jié)L動(dòng)
if images_count >= max_images:
break
# 滾動(dòng)到底部
self.driver.execute_script(
"window.scrollTo(0, document.body.scrollHeight);"
)
# 等待新圖片加載
time.sleep(1.5)
scroll_count += 1
# 檢查是否有"加載更多"按鈕
try:
load_more = self.driver.find_element(By.CLASS_NAME, 'btn_seemore')
if load_more.is_displayed():
load_more.click()
print(" 點(diǎn)擊'加載更多'按鈕")
time.sleep(2)
except:
pass
print(f"滾動(dòng)完成,共加載 {images_count} 張圖片")
return images_count
def _parse_images(self, max_count):
"""
解析圖片信息
返回:
圖片數(shù)據(jù)列表
"""
images_data = []
seen_urls = set() # 用于跟蹤已經(jīng)處理過(guò)的圖片URL
# 查找所有圖片元素
image_elements = self.driver.find_elements(
By.CSS_SELECTOR, '.imgpt .iusc'
)[:max_count] # 只取前max_count張
for idx, img_element in enumerate(image_elements):
try:
# 獲取圖片的m屬性(包含圖片信息的JSON)
m_value = img_element.get_attribute('m')
if m_value:
# 解析JSON數(shù)據(jù)
img_info = json.loads(m_value)
# 獲取圖片URL
image_url = img_info.get('murl', '')
# 檢查是否已經(jīng)處理過(guò)這張圖片,避免重復(fù)
if image_url in seen_urls:
continue
seen_urls.add(image_url)
# 提取我們需要的信息
image_data = {
'序號(hào)': len(images_data) + 1, # 使用實(shí)際添加到列表中的順序編號(hào)
'標(biāo)題': img_info.get('t', '無(wú)標(biāo)題'),
'描述': img_info.get('desc', '無(wú)描述'),
'圖片URL': image_url,
'縮略圖URL': img_info.get('turl', ''),
'寬度': img_info.get('w', '未知'),
'高度': img_info.get('h', '未知'),
'文件類(lèi)型': img_info.get('ity', '未知'),
'來(lái)源網(wǎng)站': img_info.get('purl', ''),
'域名': img_info.get('p', ''),
'采集時(shí)間': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
images_data.append(image_data)
# 顯示進(jìn)度
if len(images_data) % 10 == 0:
print(f" 已解析 {len(images_data)} 張圖片...")
except Exception as e:
print(f" 解析第 {idx + 1} 張圖片時(shí)出錯(cuò): {str(e)}")
continue
return images_data
def save_data(self, images_data, keyword):
"""
保存數(shù)據(jù)到文件
參數(shù):
images_data: 圖片數(shù)據(jù)列表
keyword: 搜索關(guān)鍵詞(用于命名文件)
"""
if not images_data:
print("沒(méi)有數(shù)據(jù)可保存")
return
# 生成文件名(包含時(shí)間戳)
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
base_filename = f"{keyword}_{timestamp}"
# 1. 保存為JSON文件
json_file = os.path.join(self.data_dir, f"{base_filename}.json")
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(images_data, f, ensure_ascii=False, indent=2)
# 2. 保存為CSV文件(用Excel可以打開(kāi))
csv_file = os.path.join(self.data_dir, f"{base_filename}.csv")
with open(csv_file, 'w', encoding='utf-8', newline='') as f:
# 寫(xiě)入表頭
fieldnames = images_data[0].keys()
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
# 寫(xiě)入數(shù)據(jù)
for img in images_data:
writer.writerow(img)
# 3. 保存為簡(jiǎn)易文本文件(方便查看)
txt_file = os.path.join(self.data_dir, f"{base_filename}.txt")
with open(txt_file, 'w', encoding='utf-8') as f:
f.write(f"搜索關(guān)鍵詞: {keyword}\n")
f.write(f"采集時(shí)間: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"圖片數(shù)量: {len(images_data)}\n")
f.write("=" * 50 + "\n\n")
for img in images_data:
f.write(f"圖片 {img['序號(hào)']}:\n")
f.write(f" 標(biāo)題: {img['標(biāo)題']}\n")
f.write(f" 描述: {img['描述']}\n")
f.write(f" 尺寸: {img['寬度']}x{img['高度']}\n")
f.write(f" 類(lèi)型: {img['文件類(lèi)型']}\n")
f.write(f" 圖片URL: {img['圖片URL'][:80]}...\n")
f.write("-" * 30 + "\n")
print(f"\n數(shù)據(jù)已保存到:")
print(f" JSON文件: {json_file}")
print(f" CSV文件: {csv_file}")
print(f" 文本文件: {txt_file}")
def display_sample_data(self, images_data, count=10):
"""
顯示示例數(shù)據(jù)
參數(shù):
images_data: 圖片數(shù)據(jù)列表
count: 顯示前幾條數(shù)據(jù)
"""
if not images_data:
print("沒(méi)有數(shù)據(jù)可顯示")
return
print(f"\n前 {min(count, len(images_data))} 條數(shù)據(jù)示例:")
print("=" * 60)
for i, img in enumerate(images_data[:count]):
print(f"{img['序號(hào)']}. {img['標(biāo)題']}")
print(f" 描述: {img['描述'][:80]}..." if len(img['描述']) > 80 else f" 描述: {img['描述']}")
print(f" 尺寸: {img['寬度']}x{img['高度']}")
print(f" 類(lèi)型: {img['文件類(lèi)型']}")
print()
def close(self):
"""關(guān)閉瀏覽器"""
self.driver.quit()
print("瀏覽器已關(guān)閉")
def main():
"""主程序"""
print("=" * 50)
print("Bing圖片爬蟲(chóng) - 新手實(shí)戰(zhàn)教程")
print("=" * 50)
# 用戶(hù)配置
keyword = "小黑子" # 可以修改為其他關(guān)鍵詞,如"動(dòng)物"、"汽車(chē)"等
max_images = 10 # 想要獲取的圖片數(shù)量
headless = False # 新手建議設(shè)為False,可以看到瀏覽器操作
# 創(chuàng)建爬蟲(chóng)實(shí)例
crawler = BingImageCrawler(headless=headless)
try:
# 搜索圖片
images_data = crawler.search_images(keyword, max_images)
if images_data:
# 顯示示例數(shù)據(jù)
crawler.display_sample_data(images_data, count=3)
# 保存數(shù)據(jù)
crawler.save_data(images_data, keyword)
# 用戶(hù)交互
print("\n" + "=" * 50)
choice = input("是否查看所有圖片標(biāo)題?(y/n): ").lower()
if choice == 'y':
print("\n所有圖片標(biāo)題:")
for img in images_data:
print(f" {img['序號(hào)']:2d}. {img['標(biāo)題']}")
else:
print("未能獲取圖片數(shù)據(jù),請(qǐng)檢查網(wǎng)絡(luò)或重試")
except KeyboardInterrupt:
print("\n用戶(hù)中斷操作")
except Exception as e:
print(f"\n程序運(yùn)行出錯(cuò): {str(e)}")
print("可能的原因:")
print(" 1. 網(wǎng)絡(luò)連接問(wèn)題")
print(" 2. 瀏覽器驅(qū)動(dòng)問(wèn)題,請(qǐng)重新運(yùn)行程序")
print(" 3. 網(wǎng)頁(yè)結(jié)構(gòu)已變化,需要更新代碼")
finally:
# 確保瀏覽器被關(guān)閉
input("\n按回車(chē)鍵退出程序...")
crawler.close()
# 程序入口
if __name__ == "__main__":
main()
"""
Bing圖片爬蟲(chóng) - Selenium新手實(shí)戰(zhàn)教程
功能:自動(dòng)搜索并獲取Bing圖片信息
"""
# 導(dǎo)入所需庫(kù)
import os
import time
import json
import csv
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
class BingImageCrawler:
"""Bing圖片爬蟲(chóng)類(lèi)"""
def __init__(self, headless=False):
"""
初始化爬蟲(chóng)
參數(shù):
headless: 是否使用無(wú)頭模式(不顯示瀏覽器窗口)
默認(rèn)False顯示窗口,適合新手調(diào)試
"""
print("=" * 50)
print("Bing圖片爬蟲(chóng) - 初始化中...")
print("=" * 50)
# 創(chuàng)建保存數(shù)據(jù)的文件夾
self.data_dir = "bing_images_data"
if not os.path.exists(self.data_dir):
os.makedirs(self.data_dir)
print(f"創(chuàng)建文件夾: {self.data_dir}")
# 設(shè)置瀏覽器選項(xiàng)
options = webdriver.ChromeOptions()
# 如果設(shè)置為無(wú)頭模式,不顯示瀏覽器窗口
if headless:
options.add_argument('--headless')
print("啟用無(wú)頭模式(不顯示瀏覽器窗口)")
# 其他配置
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1920,580') # 設(shè)置窗口大小
# 使用DriverManager自動(dòng)管理瀏覽器驅(qū)動(dòng)
print("正在下載/配置Chrome瀏覽器驅(qū)動(dòng)...")
service = Service(ChromeDriverManager().install())
# 啟動(dòng)瀏覽器
self.driver = webdriver.Chrome(service=service, options=options)
# 設(shè)置等待時(shí)間
self.wait = WebDriverWait(self.driver, 5)
print("瀏覽器啟動(dòng)成功!")
def search_images(self, keyword, max_images=10):
"""
搜索圖片
參數(shù):
keyword: 搜索關(guān)鍵詞,如"小黑子"
max_images: 最大圖片數(shù)量
返回:
圖片數(shù)據(jù)列表
"""
print(f"\n開(kāi)始搜索: {keyword}")
try:
# 1. 訪問(wèn)Bing圖片搜索
search_url = f"https://cn.bing.com/images/search?q={keyword}"
self.driver.get(search_url)
print(f"訪問(wèn)URL: {search_url}")
# 等待頁(yè)面加載
time.sleep(2)
# 2. 等待搜索框出現(xiàn)(確認(rèn)頁(yè)面加載完成)
try:
search_box = self.wait.until(
EC.presence_of_element_located((By.ID, "sb_form_q"))
)
print("頁(yè)面加載完成")
except:
print("頁(yè)面加載異常,但繼續(xù)執(zhí)行...")
# 3. 滾動(dòng)加載更多圖片
print("開(kāi)始滾動(dòng)加載圖片...")
loaded_count = self._scroll_to_load_images(max_images)
# 4. 獲取圖片數(shù)據(jù)
print("開(kāi)始解析圖片信息...")
images_data = self._parse_images(loaded_count)
if images_data:
print(f"成功獲取 {len(images_data)} 張圖片信息")
else:
print("未找到圖片數(shù)據(jù)")
return images_data
except Exception as e:
print(f"搜索過(guò)程中發(fā)生錯(cuò)誤: {str(e)}")
return []
def _scroll_to_load_images(self, max_images):
"""
滾動(dòng)頁(yè)面加載更多圖片
返回:
加載的圖片數(shù)量
"""
images_count = 0
scroll_count = 0
max_scroll = 1 # 最大滾動(dòng)次數(shù)
while images_count < max_images and scroll_count < max_scroll:
# 獲取當(dāng)前圖片數(shù)量
current_images = self.driver.find_elements(
By.CSS_SELECTOR, '.imgpt .iusc'
)
images_count = len(current_images)
print(f" 已加載 {images_count} 張圖片")
# 如果已達(dá)到目標(biāo)數(shù)量,停止?jié)L動(dòng)
if images_count >= max_images:
break
# 滾動(dòng)到底部
self.driver.execute_script(
"window.scrollTo(0, document.body.scrollHeight);"
)
# 等待新圖片加載
time.sleep(1.5)
scroll_count += 1
# 檢查是否有"加載更多"按鈕
try:
load_more = self.driver.find_element(By.CLASS_NAME, 'btn_seemore')
if load_more.is_displayed():
load_more.click()
print(" 點(diǎn)擊'加載更多'按鈕")
time.sleep(2)
except:
pass
print(f"滾動(dòng)完成,共加載 {images_count} 張圖片")
return images_count
def _parse_images(self, max_count):
"""
解析圖片信息
返回:
圖片數(shù)據(jù)列表
"""
images_data = []
seen_urls = set() # 用于跟蹤已經(jīng)處理過(guò)的圖片URL
# 查找所有圖片元素
image_elements = self.driver.find_elements(
By.CSS_SELECTOR, '.imgpt .iusc'
)[:max_count] # 只取前max_count張
for idx, img_element in enumerate(image_elements):
try:
# 獲取圖片的m屬性(包含圖片信息的JSON)
m_value = img_element.get_attribute('m')
if m_value:
# 解析JSON數(shù)據(jù)
img_info = json.loads(m_value)
# 獲取圖片URL
image_url = img_info.get('murl', '')
# 檢查是否已經(jīng)處理過(guò)這張圖片,避免重復(fù)
if image_url in seen_urls:
continue
seen_urls.add(image_url)
# 提取我們需要的信息
image_data = {
'序號(hào)': len(images_data) + 1, # 使用實(shí)際添加到列表中的順序編號(hào)
'標(biāo)題': img_info.get('t', '無(wú)標(biāo)題'),
'描述': img_info.get('desc', '無(wú)描述'),
'圖片URL': image_url,
'縮略圖URL': img_info.get('turl', ''),
'寬度': img_info.get('w', '未知'),
'高度': img_info.get('h', '未知'),
'文件類(lèi)型': img_info.get('ity', '未知'),
'來(lái)源網(wǎng)站': img_info.get('purl', ''),
'域名': img_info.get('p', ''),
'采集時(shí)間': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
images_data.append(image_data)
# 顯示進(jìn)度
if len(images_data) % 10 == 0:
print(f" 已解析 {len(images_data)} 張圖片...")
except Exception as e:
print(f" 解析第 {idx + 1} 張圖片時(shí)出錯(cuò): {str(e)}")
continue
return images_data
def save_data(self, images_data, keyword):
"""
保存數(shù)據(jù)到文件
參數(shù):
images_data: 圖片數(shù)據(jù)列表
keyword: 搜索關(guān)鍵詞(用于命名文件)
"""
if not images_data:
print("沒(méi)有數(shù)據(jù)可保存")
return
# 生成文件名(包含時(shí)間戳)
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
base_filename = f"{keyword}_{timestamp}"
# 1. 保存為JSON文件
json_file = os.path.join(self.data_dir, f"{base_filename}.json")
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(images_data, f, ensure_ascii=False, indent=2)
# 2. 保存為CSV文件(用Excel可以打開(kāi))
csv_file = os.path.join(self.data_dir, f"{base_filename}.csv")
with open(csv_file, 'w', encoding='utf-8', newline='') as f:
# 寫(xiě)入表頭
fieldnames = images_data[0].keys()
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
# 寫(xiě)入數(shù)據(jù)
for img in images_data:
writer.writerow(img)
# 3. 保存為簡(jiǎn)易文本文件(方便查看)
txt_file = os.path.join(self.data_dir, f"{base_filename}.txt")
with open(txt_file, 'w', encoding='utf-8') as f:
f.write(f"搜索關(guān)鍵詞: {keyword}\n")
f.write(f"采集時(shí)間: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"圖片數(shù)量: {len(images_data)}\n")
f.write("=" * 50 + "\n\n")
for img in images_data:
f.write(f"圖片 {img['序號(hào)']}:\n")
f.write(f" 標(biāo)題: {img['標(biāo)題']}\n")
f.write(f" 描述: {img['描述']}\n")
f.write(f" 尺寸: {img['寬度']}x{img['高度']}\n")
f.write(f" 類(lèi)型: {img['文件類(lèi)型']}\n")
f.write(f" 圖片URL: {img['圖片URL'][:80]}...\n")
f.write("-" * 30 + "\n")
print(f"\n數(shù)據(jù)已保存到:")
print(f" JSON文件: {json_file}")
print(f" CSV文件: {csv_file}")
print(f" 文本文件: {txt_file}")
def display_sample_data(self, images_data, count=10):
"""
顯示示例數(shù)據(jù)
參數(shù):
images_data: 圖片數(shù)據(jù)列表
count: 顯示前幾條數(shù)據(jù)
"""
if not images_data:
print("沒(méi)有數(shù)據(jù)可顯示")
return
print(f"\n前 {min(count, len(images_data))} 條數(shù)據(jù)示例:")
print("=" * 60)
for i, img in enumerate(images_data[:count]):
print(f"{img['序號(hào)']}. {img['標(biāo)題']}")
print(f" 描述: {img['描述'][:80]}..." if len(img['描述']) > 80 else f" 描述: {img['描述']}")
print(f" 尺寸: {img['寬度']}x{img['高度']}")
print(f" 類(lèi)型: {img['文件類(lèi)型']}")
print()
def close(self):
"""關(guān)閉瀏覽器"""
self.driver.quit()
print("瀏覽器已關(guān)閉")
def main():
"""主程序"""
print("=" * 50)
print("Bing圖片爬蟲(chóng) - 新手實(shí)戰(zhàn)教程")
print("=" * 50)
# 用戶(hù)配置
keyword = "小黑子" # 可以修改為其他關(guān)鍵詞,如"動(dòng)物"、"汽車(chē)"等
max_images = 10 # 想要獲取的圖片數(shù)量
headless = False # 新手建議設(shè)為False,可以看到瀏覽器操作
# 創(chuàng)建爬蟲(chóng)實(shí)例
crawler = BingImageCrawler(headless=headless)
try:
# 搜索圖片
images_data = crawler.search_images(keyword, max_images)
if images_data:
# 顯示示例數(shù)據(jù)
crawler.display_sample_data(images_data, count=3)
# 保存數(shù)據(jù)
crawler.save_data(images_data, keyword)
# 用戶(hù)交互
print("\n" + "=" * 50)
choice = input("是否查看所有圖片標(biāo)題?(y/n): ").lower()
if choice == 'y':
print("\n所有圖片標(biāo)題:")
for img in images_data:
print(f" {img['序號(hào)']:2d}. {img['標(biāo)題']}")
else:
print("未能獲取圖片數(shù)據(jù),請(qǐng)檢查網(wǎng)絡(luò)或重試")
except KeyboardInterrupt:
print("\n用戶(hù)中斷操作")
except Exception as e:
print(f"\n程序運(yùn)行出錯(cuò): {str(e)}")
print("可能的原因:")
print(" 1. 網(wǎng)絡(luò)連接問(wèn)題")
print(" 2. 瀏覽器驅(qū)動(dòng)問(wèn)題,請(qǐng)重新運(yùn)行程序")
print(" 3. 網(wǎng)頁(yè)結(jié)構(gòu)已變化,需要更新代碼")
finally:
# 確保瀏覽器被關(guān)閉
input("\n按回車(chē)鍵退出程序...")
crawler.close()
# 程序入口
if __name__ == "__main__":
main()8.3 代碼分步解析
第一步:導(dǎo)入庫(kù)
import os # 文件操作 import time # 時(shí)間等待 import json # JSON數(shù)據(jù)處理 import csv # CSV文件處理 from datetime import datetime # 時(shí)間處理
第二步:創(chuàng)建爬蟲(chóng)類(lèi)
class BingImageCrawler:
def __init__(self, headless=False):
# 初始化代碼第三步:搜索圖片
def search_images(self, keyword, max_images=10):
# 訪問(wèn)Bing
# 等待加載
# 滾動(dòng)加載
# 解析數(shù)據(jù)第四步:滾動(dòng)加載
def _scroll_to_load_images(self, max_images):
# 不斷滾動(dòng)直到加載足夠圖片
# 處理"加載更多"按鈕第五步:解析數(shù)據(jù)
def _parse_images(self, max_count):
# 獲取每個(gè)圖片元素的JSON數(shù)據(jù)
# 提取標(biāo)題、描述、URL等信息第六步:保存數(shù)據(jù)
def save_data(self, images_data, keyword):
# 保存為JSON格式
# 保存為CSV格式(Excel可打開(kāi))
# 保存為文本格式8.4 如何運(yùn)行程序
- 保存代碼:將上面的完整代碼保存為
bing_crawler.py - 運(yùn)行程序:
python bing_crawler.py
- 你會(huì)看到:
- 自動(dòng)打開(kāi)Chrome瀏覽器
- 訪問(wèn)Bing圖片搜索
- 搜索"
小黑子"圖片 - 自動(dòng)滾動(dòng)加載更多圖片
- 獲取圖片信息
- 保存到文件
- 在控制臺(tái)顯示結(jié)果
- 查看結(jié)果:
- 在程序所在目錄會(huì)創(chuàng)建
bing_images_data文件夾 - 里面包含3個(gè)文件:
小黑子_時(shí)間戳.json:完整JSON數(shù)據(jù)小黑子_時(shí)間戳.csv:Excel可打開(kāi)的表格小黑子_時(shí)間戳.txt:易讀的文本格式
- 在程序所在目錄會(huì)創(chuàng)建
8.5 修改配置嘗試
你可以修改代碼中的配置:
# 修改搜索關(guān)鍵詞 keyword = "動(dòng)物" # 改為"汽車(chē)"、"美食"、"星空"等 # 修改圖片數(shù)量 max_images = 20 # 想要獲取的圖片數(shù)量 # 修改是否顯示瀏覽器 headless = True # True不顯示瀏覽器(后臺(tái)運(yùn)行),F(xiàn)alse顯示瀏覽器
九、常見(jiàn)問(wèn)題與解決方法
問(wèn)題1:找不到元素(NoSuchElementException)
錯(cuò)誤信息:
selenium.common.exceptions.NoSuchElementException: Message: no such element
可能原因:
- 元素還沒(méi)加載出來(lái)
- 元素ID/名稱(chēng)已改變
- 頁(yè)面有iframe框架
解決方法:
# 1. 增加等待時(shí)間
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "element_id"))
)
# 2. 使用其他定位方式
# 如果id找不到,試試name、class、xpath等
# 3. 檢查是否有iframe
driver.switch_to.frame("iframe_name_or_id") # 切換到iframe
# 操作元素...
driver.switch_to.default_content() # 切換回主頁(yè)面問(wèn)題2:元素不可點(diǎn)擊(ElementNotInteractableException)
錯(cuò)誤信息:
ElementNotInteractableException: element not interactable
可能原因:
- 元素被其他元素遮擋
- 元素不可見(jiàn)(display: none)
- 元素還沒(méi)加載完成
解決方法:
# 1. 等待元素可點(diǎn)擊
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "element_id"))
)
# 2. 使用JavaScript點(diǎn)擊
driver.execute_script("arguments[0].click();", element)
# 3. 滾動(dòng)到元素位置
driver.execute_script("arguments[0].scrollIntoView();", element)
element.click()問(wèn)題3:超時(shí)錯(cuò)誤(TimeoutException)
錯(cuò)誤信息:
TimeoutException: Message: timeout waiting for element
解決方法:
# 1. 增加等待時(shí)間 wait = WebDriverWait(driver, 20) # 從10秒增加到20秒 # 2. 設(shè)置更頻繁的檢查 wait = WebDriverWait(driver, 10, 0.1) # 每0.1秒檢查一次 # 3. 檢查網(wǎng)絡(luò)或網(wǎng)站狀態(tài)
問(wèn)題4:瀏覽器驅(qū)動(dòng)問(wèn)題
錯(cuò)誤信息:
WebDriverException: Message: 'chromedriver' executable needs to be in PATH
解決方法:
確保安裝了webdriver-manager并正確使用:
# 正確的方式 from webdriver_manager.chrome import ChromeDriverManager service = Service(ChromeDriverManager().install()) driver = webdriver.Chrome(service=service)
十、學(xué)習(xí)建議與下一步
10.1 給新手的建議
- 從簡(jiǎn)單開(kāi)始:先運(yùn)行示例代碼,理解每行代碼的作用
- 多練習(xí):修改代碼中的參數(shù),觀察變化
- 善用打印:使用print()輸出中間結(jié)果,方便調(diào)試
- 分步調(diào)試:不要一次性寫(xiě)太多代碼,寫(xiě)完一小段就測(cè)試
10.2 練習(xí)題目
- 基礎(chǔ)練習(xí):修改代碼,爬取"動(dòng)物"或"汽車(chē)"圖片
- 進(jìn)階練習(xí):添加功能,自動(dòng)下載前5張圖片到本地
- 挑戰(zhàn)練習(xí):爬取其他網(wǎng)站,如豆瓣電影、知乎熱點(diǎn)等
10.3 下一步學(xué)習(xí)方向
- 處理復(fù)雜網(wǎng)站:學(xué)習(xí)處理登錄、驗(yàn)證碼、Ajax加載
- 提高效率:學(xué)習(xí)多線程、分布式爬蟲(chóng)
- 避免被封:學(xué)習(xí)使用代理、隨機(jī)延遲、偽裝瀏覽器
- 數(shù)據(jù)存儲(chǔ):學(xué)習(xí)使用數(shù)據(jù)庫(kù)(MySQL、MongoDB)
十一、總結(jié)
通過(guò)本教程,你已經(jīng)學(xué)會(huì)了:
? Selenium基礎(chǔ):安裝、啟動(dòng)瀏覽器、基本操作
? 元素定位:8種定位方式,找到網(wǎng)頁(yè)上的任何元素
? 元素操作:點(diǎn)擊、輸入、獲取信息、處理表單
? 等待機(jī)制:顯式等待、隱式等待,處理動(dòng)態(tài)加載
? 實(shí)戰(zhàn)項(xiàng)目:完整的Bing圖片爬蟲(chóng),包含數(shù)據(jù)保存
Selenium是一個(gè)強(qiáng)大的工具,不僅可以用于爬蟲(chóng),還可以用于自動(dòng)化測(cè)試、自動(dòng)化辦公等?,F(xiàn)在你已經(jīng)有了堅(jiān)實(shí)的基礎(chǔ),可以繼續(xù)探索更多高級(jí)功能了!
記住:學(xué)習(xí)編程最好的方式就是動(dòng)手實(shí)踐。復(fù)制代碼運(yùn)行一次,然后嘗試修改它,最后嘗試自己從頭寫(xiě)一個(gè)類(lèi)似的項(xiàng)目。
祝你學(xué)習(xí)順利!如果有問(wèn)題,可以隨時(shí)查閱Selenium官方文檔或在線搜索解決方案。
到此這篇關(guān)于Python Selenium 從零開(kāi)始掌握瀏覽器自動(dòng)化(超詳細(xì)新手教程)的文章就介紹到這了,更多相關(guān)Python Selenium 瀏覽器自動(dòng)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Python實(shí)現(xiàn)圖像分割增強(qiáng)的兩種方法
圖像分割就是把圖像分成若干個(gè)特定的、具有獨(dú)特性質(zhì)的區(qū)域并提出感興趣目標(biāo)的技術(shù)和過(guò)程。本文將為大家分享兩個(gè)用Python實(shí)現(xiàn)像分割增強(qiáng)的方法,需要的可以參考一下2022-03-03
Python基礎(chǔ)練習(xí)之用戶(hù)登錄實(shí)現(xiàn)代碼分享
這篇文章主要介紹了Python基礎(chǔ)練習(xí)之用戶(hù)登錄實(shí)現(xiàn)代碼分享,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-11-11
python實(shí)現(xiàn)視頻讀取和轉(zhuǎn)化圖片
今天小編就為大家分享一篇python實(shí)現(xiàn)視頻讀取和轉(zhuǎn)化圖片,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
使用Python去除字符串中某個(gè)字符的多種實(shí)現(xiàn)方式比較
python中字符串是不可變的,所以無(wú)法直接刪除字符串之間的特定字符,下面這篇文章主要給大家介紹了關(guān)于使用Python去除字符串中某個(gè)字符的多種實(shí)現(xiàn)方式比較的相關(guān)資料,需要的朋友可以參考下2022-06-06
python 基于dlib庫(kù)的人臉檢測(cè)的實(shí)現(xiàn)
這篇文章主要介紹了python 基于dlib庫(kù)的人臉檢測(cè)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
使用Python的內(nèi)建模塊collections的教程
這篇文章主要介紹了使用Python的內(nèi)建模塊collections的教程,示例代碼基于Python2.x版本,需要的朋友可以參考下2015-04-04

