selenium浏览器自动化
chrome驱动
https://chromedriver.storage.googleapis.com/index.html
https://chromedriver.chromium.org/downloads
https://googlechromelabs.github.io/chrome-for-testing/
简单示范
from selenium import webdriver #引入基础
from selenium.webdriver.chrome.service import Service #引入chrome服务
service = Service('chromedriver112.exe') #指定驱动文件
chrome = webdriver.Chrome(service=service) #给予对象
chrome.get('https://www.baidu.com')
因为selenium默认只会创建新的浏览器实例,因此每次都会丢失缓存,这不是我需要的,所以我需要在现有的实例中工作,因此我需要手动添加一个chrome的快捷启动方式,并添加启动参数:--remote-debugging-port=9222
下面是一个例子:
from selenium import webdriver #引入基础
from selenium.webdriver.chrome.service import Service #引入chrome服务
from selenium.webdriver.common.by import By #导入网页元素选择器
service = Service('chromedriver112.exe') #指定驱动程序路径
options = webdriver.ChromeOptions() #开启设置
# options.add_argument('--proxy-server=socks5://127.0.0.1:1080') 这是为chrome添加启动参数的方法
#设置远程调试端口,如果不这样,chrome将会打开新实例,每次都会丢失缓存
options.debugger_address = "localhost:9222"
# 对象给chrome变量,并应用驱动和设置,options可以不设置,因为这里要调用远程调试端口可以需要开启
chrome = webdriver.Chrome(service=service, options=options)
chrome.implicitly_wait(30) #设置全局的网页元素等待超时时间
chrome.get('https://www.baidu.com')
chrome.find_element(By.ID,'kw').send_keys('你好') #向网页ID名为kw的元素,输入内容‘你好’
chrome.find_element(By.ID,'su').click() #元素点击
#新版的selenium会在执行完任务后自动关闭chrome,所以我添加了一个等待输入防止自动关闭,如果是开启远程调试端口则无效
#input("输入回车结束")
注意chrome.find_element方法,如果匹配到多个元素,则只取第一个,如果要匹配多个,请在后面加个s的方法
在很难定位的时候,可以使用多级,例如它只有一个class名,你怕它匹配到多个,则可以使用多个元素查找,例如chrome.find_element(By.CSS_SELECTOR,'#su .guide') #代表id=su 标签内的 class=guide
元素类型标记
- class 使用 .class
- id 使用 #id
- 标签类型直接用标签例如 div
- name直接属性值例如 name=my-name
- 链接文本 直接用文本就行
下面是一些取内容的方法:
chrome.find_element(By.ID,'su').text #获取元素文本内容
chrome.find_element(By.ID,'su').get_attribute('title') #获取属性值,例如超链接的title属性值,
#判断元素是否存在,如果不存在会报错,
if len(chrome.find_elements(By.CLASS_NAME, 'div.od-pc-offer-cross')) > 0:
#使用复数获取列表,如果找到符合的会大于0
chrome.find_element(By.ID,'su').is_displayed() #是否可见
chrome.find_element(By.ID,'su').is_enabled() #是否可用
#取html代码
chrome.find_element(By.CSS_SELECTOR,"div.offer-attr-wrapper").get_property("outerHTML")
print(chrome.title) #当前页面标题
print(chrome.current_url) #当前页面链接
下面是取列表的示范:
list = chrome.find_elements(By.CSS_SELECTOR,'.shoplist li') #找class是shoplis下面的所有li标签
for li in list:
print(li.find_element(By.CSS_SELECTOR,'a').get_attribute('title')) #获取单个li的a标签的标题属性
print(li.find_element(By.CSS_SELECTOR,'.search_price').text) #获取单个li的当前价格
浏览器自身的操作
chrome.maximize_window() #最大化浏览器窗口
chrome.quit() #关闭浏览器
chrome.close() #关闭标签页
chrome.set_window_size(300,300) #设置浏览器尺寸
chrome.set_window_position(200,300) #设置浏览器位置
chrome.back() #浏览器后会按钮
chrome.forward() #浏览器前进按钮
chrome.refresh() #标签页刷新
连续动作
from selenium.webdriver import ActionChains #导入连续动作模块
ActionChains(chrome).move_to_element().click().perform() #连续动作
#格式:ActionChains(chrome) + 下方动作 +perform()结尾
鼠标动作
context_click() #鼠标右键点击
double_click() #鼠标双击
drag_and_drop() #双击拖拽
move_to_element() #鼠标悬停
键盘动作
from selenium.webdriver.common.keys import Keys #导入键盘按键
send_keys(Keys.BACK_SPACE) #删除键
send_keys(Keys.SPACE) #空格键
send_keys(Keys.TAB) #TAB键
send_keys(Keys.ESCAPE) #Esc键
send_keys(Keys.ENTER) #回车键
send_keys(Keys.CONTROL,'a') #ctrl+a
send_keys(Keys.CONTROL,'c') #ctrl+c
一些有用的操作
sleep(5) #延时5秒,需要引入from time import sleep
chrome.execute_script('window.scrollTo(0,1000)') #滚动条,横向,纵向滚动1000
chrome.get_screenshot_as_file('./demo.png') #网页截图
多标签页操作
#chrome.window_handles 是取当前窗口总个数
if len(chrome.window_handles) > 1: #保留1个标签页
for i in range(len(chrome.window_handles) - 1): #判断要删除的窗口执行次数
chrome.switch_to.window(chrome.window_handles[1])
chrome.close()
#因为每删除一个窗口就自动少了一个了,其他的会自动变成2,所以只要不停删除1就行
chrome.switch_to.window(chrome.window_handles[0])
chrome.switch_to.new_window('tab')
##窗口执行与操作
chrome.get('https://s.1688.com/selloffer/offer_search.htm?keywords=%C5%AE%D7%B0') #当前是操作主窗口
chrome.switch_to.new_window('tab') #创建新标签页,并启动切换到该标签页
chrome.get('https://www.bing.com/') #当前是操作副窗口
chrome.close() #关闭标签
chrome.switch_to.window(chrome.window_handles[0]) #切换到主标签页1就是切换到副窗口
chrome.get('https://www.bing.com/') #当前是操作主窗口
列表正则取数
splb=[]
for list in lists:
#取商品ID
quid = list.find_element(By.CSS_SELECTOR,'div div').get_attribute('data-aplus-report')
pattern = r'object_id@(\d+)\^'
lsspid = re.findall(pattern, quid)[0]
splb.append(lsspid)
代码块中取文字
from bs4 import BeautifulSoup #html解析
wenzi = BeautifulSoup(wenzi, 'html.parser')
# 提取文本内容
wenzi = wenzi.get_text()
print(f'文字描述:{wenzi}')
保存图片示范
#创建文件夹
os.makedirs(f"info/{sp}", exist_ok=True)
#创建文件
print('开始创建文件')
with open(f"info/{sp}/{shangpin_biaoti}.txt", 'w',encoding='utf-8') as file:
file.write(f"商品ID:{sp}\n标题:{shangpin_biaoti}\n链接:{url}\n颜色种数:{zongsku}\n颜色类别:{skuname}\n文字描述:{wenzi}")
#创建图片文件夹
os.makedirs(f"info/{sp}/img", exist_ok=True)
#提取图片
print('开始提取图片')
img1 = chrome.find_element(By.CSS_SELECTOR,'div#detailContentContainer')
imgs = img1.find_elements(By.TAG_NAME, 'img')
print('开始图片列表')
srcs = []
for img in imgs:
data_lazyload_src = img.get_attribute('data-lazyload-src')
if data_lazyload_src:
src = data_lazyload_src
else:
src = img.get_attribute('src')
srcs.append(src)
print('切换标签3浏览器')
chrome.switch_to.window(chrome.window_handles[2])
print('开始图打开图片')
i = 0
for src in srcs:
i += 1
chrome.get(src)
sleep(1)
b64img = chrome.execute_script(r'''
var img = document.getElementsByTagName("img")[0];
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
''')
# 将Base64编码的图片数据解码
img_data = b64decode(b64img)
# 将解码后的字节码保存为图片
with open(f"info/{sp}/img/{i}.jpg", "wb") as file:
file.write(img_data)
print(f'保存图片{src}')