Home » 笔记 » 【笔记】Python3 中使用 Selenium 针对性获取图片和文字

【笔记】Python3 中使用 Selenium 针对性获取图片和文字

发布于 April 4, 2022 笔记

Selenium v4 与 Webdriver 的安装

$ pip3 install -U selenium
$ pip3 install webdriver_manager

Selenium 4.0.0 即将移除 webdriver 中的 executable_path= 标签。如果手动安装 webdriver 后用 executable_path= 指定路径,则会跳出警告,影响输出。

Webdriver 初始化与连接网页

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://www.google.com")

如果需要加上浏览器选项,则在 Service() 中加上 options=options

常用 Webdriver 选项

options = webdriver.ChromeOptions()
# 初始化 options 作为设置对象
options.add_argument('--no-sandbox')
# 解决DevToolsActivePort文件不存在的报错
options.add_argument('--disable-gpu')
# 关闭 GPU(可规避部分Bug)
options.add_argument('window-size=1920x1080')
# 设置浏览器初始窗口大小
options.add_argument('--hide-scrollbars')
# 隐藏滚动条
options.add_argument('--headless')
# 无头模式,不提供可视化页面,Dos系统必须加不然报错
options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors", "enable-automation"])
# 开发者模式启动,规避检测
option.add_argument("--disable-javascript")
# 禁用JavaScript

如果要达成完全在后台操作的效果,有图形界面的电脑也可以使用 .add_argument('--headless') 切换为无头模式。

更多 Chromium 命令行开关,参考 List of Chromium Command Line Switches

Selenium 使用不同方法定位元素

from selenium.webdriver.common.by import By

driver.find_element(By.[arg]), argValue)
driver.find_elements(By.[arg]), argValue)
.find_element()
from selenium.webdriver.common.by import By

webElement = driver.find_element(arg, argValue)

arg 可以替换成任何By类可用的属性,argValue 可替换为属性的具体值,type 需要是 str。By 类可用的属性在下方表格:

argargValue
By.IDid="id"
By.XPATH"XPath"
By.LINK_TEXThref="link text"
By.PARTIAL_LINK_TEXThref="tigerding.com/partial_link_text"
By.NAMEname="name"
By.TAG_NAME<tagname></tagname>
By.CLASS_NAMEclass="class"
By.CSS_SELECTOR<p class="content"></p> "p .content"

关于 By.CSS_SELECTOR 的进阶使用,参考 Selenium Tips: CSS Selectors

.find_elements()
from selenium.webdriver.common.by import By

driver.get(baseURL + seedInput + locationX + locationY + otherAttri)
htmlElements = driver.find_elements(By.TAG_NAME,'script')
for eachElement in htmlElements:
    print(eachElement.get_attribute('innerHTML'))

这个方法和 .find_element 基本一样,只是返回的值是一个 list,list 中包含所有符合 arg 的 WebElement 类。

.get_attribute('innerHTML') 用于打印单个元素的 html 源码,如果这里不加上这个方法光用 print(eachElement) 的话,会打印出 <class 'selenium.webdriver.remote.webelement.WebElement'> 而不是 html string。

save_screenshot 与 screenshot 的区分

driver.get("https://google.com/")
googleLogo = driver.find_element(By.XPATH, '/html/body/div[1]/div[2]/div/img')
fileDir = "/Users/tiger/Downloads/google.png"
googleLogo.screenshot(fileDir[:])
print("image saved")

>>> python3 demo.py
image saved

如上方代码块所示,当需要截图的对象是已经被定位到的某个元素时,无法使用 .save_screenshot() 。因为在 WebElement 类中这个方法不是这样写的,换成了 .screenshot()。后方的 arg 完全一样,都是带有具体文件目录,包含文件名和格式。

当截图对象是已经是被定位到的某个元素时,使用 .screenshot() 即可给对应元素截图,大小为元素的原始大小,默认保存格式为png。这里要注意,针对指定元素的截图不能使用 .save_screenshot() 否则返回 AttributeError

driver.get("https://google.com/")
driver.save_screenshot("./google.png")
print("image saved")

>>> python3 demo.py
image saved

.save_screenshot() 是用在整个浏览器截图上,截图大小为浏览器窗口大小。虽然可以通过 iamge.crop((w,t,h,b)) 对浏览器窗口进行剪裁达到对元素截图的同样目的,但是需要注意必须在 webdriver.ChromeOptions() 设置好窗口大小,不然会默认为电脑屏幕的大小,裁剪不好容易跑偏。

关于 PIL 的 Image 图形处理外部库,参考 Python图像库PIL的类Image及其方法介绍

Webdriver 设置窗口大小为网页大小

browserWidth = driver.execute_script("return document.documentElement.scrollWidth")
browserHeight = driver.execute_script("return document.documentElement.scrollHeight")
driver.set_window_size(browserWidth, browserHeight)

document.documentElement 这个这个Web API 指向一般目标网站的 rootElement, 也就是最底层的元素。使用 .scrollWidth.scrollHeight 获得元素长宽,一般一整个网页的长宽就是底层元素的长宽。

.set_window_size() 是在初始化浏览器后改变窗口大小的方法。在初始化浏览器前可以使用 webdriver.ChromeOptions().add_argument(window-size=width[x]height)

阅读文章

辅助资料

Add Comment