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}')