driver.find_element(By.XPATH, ‘//*[text()=”圖片”]’).click()
“””
By.XPATH
Out[217]: ‘xpath’
“””
driver.find_element(By.XPATH, ‘//*[text()=”圖片”]’):使用 XPath 定位器尋找頁面上所有文本內容為“圖片”的元素。這里的 XPath 表達式 //*[text()=”圖片”] 表示選擇文本內容完全匹配“圖片”的所有元素。
.click():對找到的元素執行點擊操作。
請確保目標元素在頁面上是唯一的或者是你想要交雲的第一個匹配元素,因為 find_element 方法只會返回第一個匹配的元素。如果頁面上有多個元素的文本為“圖片”,並且你想要操作特定的一個,你可能需要使用更具體的 XPath 表達式來精確定位。
在 XPath 表達式中:
- // 表示選擇當前節點的所有子節點(不僅僅是直接子節點,而是所有後代節點),不論它們位於文檔中的哪個位置。
- *代表任何元素節點。因此,//* 表示選擇文檔中的所有元素。
[text()=”圖片”] 是一個條件(謂詞),用於進一步限定選擇的元素。它表示只選擇那些文本內容完全等於“圖片”的元素。
綜合來看,XPath 表達式 //*[text()=”圖片”] 會選中文檔中所有文本內容為“圖片”的元素。這是一個非常強大的特性,因為它允許您基於元素的文本內容來定位元素,而不依賴於元素的標簽類型、id 或類名等屬性。
使用這種方式時,需要注意的是,如果頁面上有多個元素包含相同的文本“圖片”,該表達式會匹配到所有這些元素。在使用 driver.find_element(By.XPATH, ‘//*[text()=”圖片”]’) 時,如果有多個匹配項,Selenium 將返回第一個找到的元素。如果您的目標是進行點擊操作,確保這是您想要交互的那個元素。如果您想要處理所有匹配的元素,可以使用 driver.find_elements 方法來獲取一個包含所有匹配元素的列表。
這段代碼 //*[text()="圖片"]
是一個XPath表達式,它用於在XML或HTML文檔中定位元素。XPath,全稱XML Path Language,是一種在XML文檔中尋找信息的語言,也被廣泛應用於與HTML文檔交互,尤其是在網頁爬蟲和自動化測試領域。這與Python語法不同,因為它是一種用於特定目的的查詢語言,而不是一種通用的編程語言。
XPath語法解釋
//
:這表示選擇文檔中的節點,而不考慮它們在文檔中的位置。//
後面跟著的是要查找的節點類型或標籤名。在這個例子中,*
代表選擇所有元素節點。*
:這是一個通配符,表示匹配任何元素節點。[text()="圖片"]
:這是一個條件表達式(預言),用於進一步限制選擇的節點。text()
函數會選擇節點的文本內容,並且這個條件指定只選擇文本內容等於”圖片”的節點。=
:在XPath中,=
用於比較運算符,檢查左側的表達式(在這個情況下是元素的文本內容)是否等於右側的值(”圖片”)。這與Python中的==
不同,因為XPath有自己的語法規則。
為什麼使用XPath
XPath提供了一種非常強大且靈活的方式來定位HTML文檔中的元素,尤其是當元素沒有唯一的ID或類名時。它允許你基於元素的層次位置、屬性、文本內容等多種特性進行精確定位。在網頁自動化測試和爬蟲領域,這種能力非常寶貴。
總結來說,//*[text()="圖片"]
這種XPath表達式的使用與Python語法不同,是因為它們服務於不同的目的,並且各自遵循著自己的語法規則和標準。XPath專門用於在XML和HTML文檔中尋找和定位元素,而Python是一種通用的編程語言,用於廣泛的應用開發。
code:
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 4 10:35:36 2024
@author: SavingKing
"""
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
import os
import json
from typing import List
option = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values":{"notifications":2}}
option.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(options=option)
#selenium.webdriver.chrome.webdriver.WebDriver
url = "https://www.google.com/"
driver.get(url)
"""#Google的搜尋框HTML:
<textarea class="gLFyf" aria-controls="Alh6id" aria-owns="Alh6id" autocomplete="off" autofocus=""
title="Google 搜尋" value="" jsaction="paste:puy29d;" aria-label="搜尋"
aria-autocomplete="both" aria-expanded="false" aria-haspopup="false"
autocapitalize="off" autocorrect="off" id="APjFqb" maxlength="2048" name="q"
role="combobox" rows="1" spellcheck="false" data-ved="0ahUKEwiO76K2vaeEAxVDjVYBHawuBO8Q39UDCAY"
aria-activedescendant="" style=""></textarea>
"""
search = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(By.CSS_SELECTOR, 'textarea[title="Google 搜尋"][aria-label="搜尋"]')
)
)
# selenium.webdriver.remote.webelement.WebElement
# search.send_keys("barbenheimer")
# search.send_keys(Keys.ENTER)
search.send_keys("barbenheimer", Keys.ENTER)
driver.find_element(By.XPATH, '//*[text()="圖片"]').click()
driver.find_element(By.XPATH, '//*[text()="工具"]').click()
driver.find_element(By.XPATH, '//*[text()="大小"]').click()
driver.find_element(By.XPATH, '//*[contains(text(), "大")]').click()
#Google可能顯示"大",也可能顯示"大型"
""" #取得縮圖網址
<div class="fR600b islir" jsname="DeysSe" style="margin-top: -1px; height: 194px;">
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/
2wCEAAoGB...省略數十行pUqIT//2Q==" data-deferred="1" class="rg_i Q4LuWd" jsname="Q4LuWd" width="145" height="194" alt="Barbenheimer” and the Rumored Death of Cinema | by Archer | Fandom Fanatics | Medium" data-iml="531.2999999523163" data-atf="true"></div>
"""
效果:
開啟Chrome後,
自動在搜尋框輸入:
barbenheimer
ENTER
再自動點選
圖片>工具>大小>大(或者: 大型,
Google會變化防爬蟲)
selenium.webdriver.remote.webelement.WebElement
在Selenium中的作用與BeautifulSoup庫中的Tag
對象非常相似,但它們是用於不同情境和目的的。
WebElement
- 定義與用途:
WebElement
是Selenium WebDriver的一部分,代表網頁上的一個元素。當你使用Selenium進行網頁自動化測試或網頁爬蟲時,WebElement
允許你與網頁上的元素互動,比如讀取其屬性、文本內容,或者對它進行點擊、填充數據等操作。 - 互動能力:
WebElement
提供了一種方式來模擬用戶對網頁元素的各種操作,這是因為Selenium模擬了一個真實的瀏覽器環境。 - 動態內容處理:Selenium非常適合於處理JavaScript生成的動態內容。由於它操作的是一個真實的瀏覽器,因此可以等待JavaScript渲染完成後再進行元素選擇和互動。
BeautifulSoup的Tag
- 定義與用途:BeautifulSoup庫中的
Tag
對象代表HTML或XML文檔中的一個標籤。BeautifulSoup主要用於解析和操作HTML或XML文檔的數據,常用於網頁數據抓取。 - 操作數據:通過BeautifulSoup,你可以輕易地查找、訪問和修改HTML標籤及其內容。它提供了豐富的方法和屬性來選擇特定元素,讀取它們的內容、屬性等。
- 靜態內容處理:BeautifulSoup主要處理靜態HTML內容。對於JavaScript動態生成的內容,BeautifulSoup本身無法直接處理,需要配合其他工具(如Selenium)來先執行JavaScript渲染。
總結來說,WebElement
和BeautifulSoup中的Tag
都代表了網頁文檔中的元素,但它們分別屬於不同的庫,並且設計用於滿足不同的自動化和數據抓取需求。Selenium更適合於需要與網頁元素進行交互或處理動態內容的場景,而BeautifulSoup則在解析和操作靜態HTML/XML數據方面更為便利。
推薦hahow線上學習python: https://igrape.net/30afN
code:
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 4 10:35:36 2024
@author: SavingKing
"""
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
import os
import json
from typing import List
import time
import requests
option = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values":{"notifications":2}}
option.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(options=option)
#selenium.webdriver.chrome.webdriver.WebDriver
url = "https://www.google.com/"
driver.get(url)
"""#Google搜尋框HTML:
<textarea class="gLFyf" aria-controls="Alh6id" aria-owns="Alh6id" autocomplete="off" autofocus=""
title="Google 搜尋" value="" jsaction="paste:puy29d;" aria-label="搜尋"
aria-autocomplete="both" aria-expanded="false" aria-haspopup="false"
autocapitalize="off" autocorrect="off" id="APjFqb" maxlength="2048" name="q"
role="combobox" rows="1" spellcheck="false" data-ved="0ahUKEwiO76K2vaeEAxVDjVYBHawuBO8Q39UDCAY"
aria-activedescendant="" style=""></textarea>
"""
search = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(By.CSS_SELECTOR, 'textarea[title="Google 搜尋"][aria-label="搜尋"]')
)
)
# selenium.webdriver.remote.webelement.WebElement
# search.send_keys("barbenheimer")
# search.send_keys(Keys.ENTER)
search.send_keys("barbenheimer", Keys.ENTER)
driver.find_element(By.XPATH, '//*[text()="圖片"]').click()
time.sleep(1)
driver.find_element(By.XPATH, '//*[text()="工具"]').click()
time.sleep(1)
driver.find_element(By.XPATH, '//*[text()="大小"]').click()
time.sleep(1)
driver.find_element(By.XPATH, '//*[contains(text(), "大")]').click()
#Google可能顯示"大",也可能顯示"大型"
""" #取得縮圖網址
<div class="fR600b islir" jsname="DeysSe" style="margin-top: -1px; height: 194px;">
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/
...省略數十行
lRCcNNalSohFSpUqIT//2Q=="
data-deferred="1" class="rg_i Q4LuWd" jsname="Q4LuWd" width="145" height="194" alt="Barbenheimer”
and the Rumored Death of Cinema | by Archer | Fandom Fanatics | Medium" data-iml="531.2999999523163" data-atf="true"></div>
<a data-ved="0CBIQjRxqFwoTCMDlvYeWtIQDFQAAAAAdAAAAABAE" class="jlTjKd" rel="noopener"
target="_blank" href="https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.storm.mg%2Flifestyle%2F4995829&psig=AOvVaw3JRbsArUfTaZQXdV3LoERH&ust=1708321046463000&source=images&cd=vfe&opi=89978449&ved=0CBIQjRxqFwoTCMDlvYeWtIQDFQAAAAAdAAAAABAE" jsaction="focus:trigger.HTIQtd;mousedown:trigger.HTIQtd;touchstart:trigger.HTIQtd;" role="link" tabindex="0" aria-label="造訪「風傳媒」" rlhc="1"><img src="https://image.cache.storm.mg/styles/smg-800x533-fp/s3/media/image/2024/01/22/20240122-033347_U29183_M927572_3dda.jpg?Mf4oEXaQ5B39A1Zm.9aHzNcPAscWS_y2&itok=SOM01Rto" jsaction="VQAsE" class="sFlh5c pT0Scc iPVvYb" style="max-width: 800px; height: 310px; margin: 0px; width: 465px;" alt="Toyz慘遭「超派鐵拳」打到頭破縫10針!統神直播曝他慣用手法:一定是故意-風傳媒" jsname="kn3ccd" aria-hidden="false"><img src="data:image/jpeg;eight="180" alt="Toyz慘遭「超派鐵拳」打到頭破縫10針!統神直播曝他慣用手法:一定是故意-風傳媒" data-iml="9373" data-atf="true">
<div class="fR600b islir" jsname="DeysSe" style="height: 159px; margin-top: 11px; margin-left: -53px; margin-right: -53px;"><img src="data:image/jpeg;base64,/9j/4A...略過v//Z" data-deferred="1" class="rg_i Q4LuWd" jsname="Q4LuWd" width="317" height="159" alt="Barbenheimer' weekend energizes the box office, brings moviegoers back to theaters" data-iml="1479" data-atf="true"></div>
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRg...略過wuwv//Z" data-deferred="1" class="rg_i Q4LuWd" jsname="Q4LuWd" width="317" height="159" alt="Barbenheimer' weekend energizes the box office, brings moviegoers back to theaters" data-iml="1479" data-atf="true">
"""
anchor:list = driver.find_elements(By.CSS_SELECTOR,'a[class="FRuiCf islib nfEiy"]')
""" len : 48
anchor[0]
<selenium.webdriver.remote.webelement.WebElement (session="e3c143e986938ea9f4247d3d1bfae922", element="0BDE533433DA6DF7C20086E92843283C_element_171")>
anchor[0].get_attribute('outerHTML')
Out[226]: '<div class="fR600b islir" jsname="DeysSe" style="margin-top: -4px; height: 215px;">
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/
2wCEAAoGBxQUExYTExQYFhYYGhkaGhkaGhkaGxgbGxoZGhoaGBkaHysiHyIoHxwaIzQjKCwuMTIxGSE3PDcwOyswMS4BCwsLDw4PHRERHTIpISgwMi4wNjAyLj
<a class="FRuiCf islib nfEiy" jsname="sTFXNd" tabindex="0" role="button"
jsaction="J9iaEb;mousedown:npT2md; touchstart:npT2md;" data-nav="1" style="height: 180px;"
href="https://www.google.com/imgres?imgurl=https%3A%2F%2Fimage.cache.storm.mg%2Fstyles%2Fsmg-800x533-fp%2Fs3%2Fmedia%2Fimage%2F2024%2F01%2F22%2F20240122-033347_U29183_M927572_3dda.jpg%3FMf4oEXaQ5B39A1Zm.9aHzNcPAscWS_y2%26itok%3DSOM01Rto&tbnid=3AYfJvxYbjJQSM&vet=12ahUKEwjcwq76lbSEAxXdVvUHHYf1CdAQMygAegQIARBP..i&imgrefurl=https%3A%2F%2Fwww.storm.mg%2Flifestyle%2F4995829&docid=FGc8Cy96G8Ad1M&w=800&h=533&q=%E8%B6%85%E6%B4%BE%E9%90%B5%E6%8B%B3&ved=2ahUKEwjcwq76lbSEAxXdVvUHHYf1CdAQMygAegQIARBP" data-navigation="server"><div class="fR600b islir" jsname="DeysSe" style="height: 180px; margin-right: -9px;"><img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/...class="rg_i Q4LuWd" jsname="Q4LuWd" width="271" height="180" alt="Toyz慘遭「超派鐵拳」打到頭破縫10針!統神直播曝他慣用手法:一定是故意-風傳媒" data-iml="9373" data-atf="true"></div><div class="Dv4WMb mvjhOe"></div></a>
"""
lis_href = []
for webElement in anchor:
try:
webElement.click()
#img = webElement.find_element(By.CSS_SELECTOR, 'a[class="FRuiCf islib nfEiy"][jsname="sTFXNd"]')
#selenium.webdriver.remote.webelement.WebElement
# img = webElement.find_element(By.CSS_SELECTOR,'a[class="FRuiCf islib nfEiy"]')
# 假设img是您已定位到的包含图片的WebElement对象
image_url = webElement.get_attribute('href') # 尝试获取data-src属性
# if not image_url: # 如果data-src不存在,尝试获取src属性
# image_url = img.get_attribute('src')
print(image_url)
lis_href.append(image_url)
# print("img:\n",img)
# print(img.get_attribute("outerHTML"))
# href = img.get_attribute('href')
# print(href)
lis_href.append(image_url)
except:
pass
pic=[]
for url in lis_href:
try:
driver.get(url)
img = WebDriverWait(driver,10).until(EC.element_to_be_clickable(
(By.CSS_SELECTOR,'img[class="sFlh5c pT0Scc iPVvYb"]')
))
pic.append(img.get_attribute("src"))
print("img src:",img.get_attribute("src"))
"""
<img src="https://static1.colliderimages.com/wordpress/wp-content/uploads/2023/11/barbenheimer-movie.jpg" jsaction="VQAsE"
class="sFlh5c pT0Scc iPVvYb" style="max-width: 1400px; height: 360px; margin: 0px; width: 719px;" alt="Barbenheimer' Is the Movie That No One Needs!" jsname="kn3ccd">
"""
except:
print("url without src:",url)
# =============================================================================
#<img src="https://miro.medium.com/v2/resize:fit:1012/1*S0Eg699v-WrW3OPfgxfSpg.jpeg" jsaction="VQAsE" class="sFlh5c pT0Scc iPVvYb" style="max-width: 1012px; height: 959px; margin: 0.5px 0px; width: 719px;" alt="Barbenheimer: The Internet Phenomenon That Became the Movie Event ..." jsname="kn3ccd">
# =============================================================================
dirname=r"C:\Users\yuwen\Downloads\芭比海默"
n=0
for url in pic:
#'https://www.google.com/imgres?imgurl=https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1012%2F1*S0Eg699v-WrW3OPfgxfSpg.jpeg&tbnid=ZQmzaZvs_N-wUM&vet=12ahUKEwiOnpjqs7SEAxUpVPUHHaazC2UQMygAegQIARBQ..i&imgrefurl=https%3A%2F%2Fmedium.com%2Fillumination%2Fbarbenheimer-the-internet-phenomenon-that-became-the-movie-event-of-the-year-3a114fdb38a8&docid=yz9JgpU3LtQ4XM&w=1012&h=1350&q=barbenheimer&ved=2ahUKEwiOnpjqs7SEAxUpVPUHHaazC2UQMygAegQIARBQ'
n+=1
try:
res = requests.get(url,stream=True)
path = os.path.join(dirname,f"芭比海默{n:03d}.jpg")
with open(path,"wb") as f:
f.write(res.content)
except:
print("url without img:",url)
輸出結果:
推薦hahow線上學習python: https://igrape.net/30afN