0


【Python爬虫】Selenium使用

文章目录

安装配置教程自行搜索

所用驱动chromedriver应与chrome浏览器版本相对应

pip install selenium

笔者selenium所用版本为4.11.2,新旧版之间会有差别

from selenium import webdriver
driver = webdriver.Chrome()

实例化driver对象后,driver对象有一些常用的属性和方法

driver.page_source #当前标签页浏览器渲染之后的网页源代码
driver.current_url #当前标签页的url
driver.close()#关闭当前标签页,如果只有一个标签页则关闭整个浏览器
driver.quit()#关闭浏览器
driver.forward()#页面前进
driver.back()#页面后退
driver.refrash()#页面刷新
driver.save_screenshot("img_name")#页面截图

我们使用Selenium时会觉得浏览器加载很慢,这和它的页面加载策略有关

Selenium的页面加载策略(pageLoadStrategy)

本段摘自https://blog.csdn.net/momoda118/article/details/120624777

  1. normal:等待整个页面加载完毕再开始执行操作(默认为此)
  2. eager:等待整个dom树加载完成,即DOMContentLoaded这个事件完成,也就是只要 HTML完全加载和解析完毕就开始执行操作。放弃等待图片、样式、子帧的加载。
  3. none:等待html下载完成,哪怕还没开始解析就开始执行操作。

加载策略设置为eager

配置代码如下:

chrome_options = Options()
chrome_options.page_load_strategy ='eager'
driver = webdriver.Chrome(options=chrome_options)

加载策略设置为none

加载策略设置为none,并引入retry做重试(目的是为了防止报错,当然设置隐式等待也可,但没retry稳妥)可以只用2s左右就能执行完成,完整代码如下:

import datetime
from retrying import retry  # 需第三方库,需pip进行安装from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

@retry(wait_fixed=10, stop_max_attempt_number=1)defclick(path):
    driver.find_element(By.XPATH, path).click()
    
chrome_options = Options()
chrome_options.page_load_strategy ='none'
driver = webdriver.Chrome(options=chrome_options)
start_time = datetime.datetime.now()
driver.get('https://www.iqiyi.com/')
click('//*[@id="block-C"]/div/div/div/div[1]/div[1]/div/div[1]/div/div/a/span[2]')
end_time = datetime.datetime.now()print(end_time - start_time)

元素定位

本段参考https://blog.csdn.net/qq_18298049/article/details/117136214

element = driver.find_element(By.ID,'kw')# 通过ID定位搜索框

element = driver.find_element(By.NAME,'wd')# 通过name定位搜索框

element = driver.find_element(By.CLASS_NAME,'s_ipt')# 获取百度首页搜索框

element = driver.find_element(By.TAG_NAME,'input')# 查找标签名称是input的元素

element = driver.find_element(By.LINK_TEXT,'贴吧')# 定位贴吧

element = driver.find_element(By.PARTIAL_LINK_TEXT,'贴')# 定位贴吧

头尾匹配写法:其中,头尾匹配可以是部分字符,部分匹配需要是按空格分隔的完整字符。
条件htmlvalues 写法1 (头部匹配)values 写法2 (尾部匹配)values 写法3 (部分匹配)class< button class=“el-button el-button–primary”>‘[class^=“el-button”]’‘[class$=“–primary”]’‘[class~=“el-button”]’

css selector

element = driver.find_element(By.CSS_SELECTOR,'#kw')# #kw id选择器
element = driver.find_element(By.CSS_SELECTOR,'.s_ipt')# .s_ipt class选择器
element = driver.find_element(By.CSS_SELECTOR,'form #kw')# 后代元素选择器
element = driver.find_element(By.CSS_SELECTOR,"input[name='wd']")# 属性值定位选择器# 同时包含两个条件# 包含type='text'与maxlength='50'两个条件的元素,语法上不需要and进行连接
driver.find_element(By.CSS_SELECTOR,'[type="text"][maxlength="50"]')# 包含一个条件且不包含另一条件# 包含type='text'且不包含maxlength='50'的元素,语法上使用:not()进行连接
driver.find_element(By.CSS_SELECTOR,'[type="text"]:not([maxlength="50"])')

xpath

相对路径

//#查找页面根元素//input#查找页面上所有的input元素//form[1]/input#查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素,使用绝对路径表示,单/号)//form[1]//input#查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号)//form[1]#查找页面上第一个form元素//form[@id='loginForm']#查找页面上id为loginForm的form元素//input[@name='username']#查找页面上具有name属性为username的input元素//form[@id='loginForm']/input[1]#查找页面上id为loginForm的form元素下的第一个input元素//input[@name='continue'][@type='button']#查找页面具有name属性为contiune并且type属性为button的input元素//form[@id='loginForm']/input[4]#查找页面上id为loginForm的form元素下第4个input元素

写法为:

element = driver.find_element(By.XPATH, '路径')

绝对路径

调试模式找到元素右键复制

不建议写绝对路径!!!

定位模糊匹配

contains关键字:

//a[contains(@href, ‘logout’)]

寻找页面中href属性值包含有logout这个单词的所有a元素

start-with关键字:

//a[starts-with(@name, ‘start)])

寻找name属性以start开头的a元素。其中@后面的name可以替换成元素的任意其他属性

text关键字:

//*[text()=’确定’]

一个简单粗暴的定位方式,无需知道属于什么标签元素,常用于纯文字查找,也可用于链接元素文本查找

//a[contains(text(), ’退出’)]

用于知道超链接上显示的部分或全部文本信息时

find_element和find_elements

  • find_element返回匹配到的第一个标签对象;find_elements返回列表
  • find_element匹配不到抛出异常;find_elements匹配不到返回空列表

元素操作

示例1:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

chrome_options = Options()
chrome_options.page_load_strategy ='eager'
service = Service('chromedriver.exe路径')

driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://www.baidu.com")
driver.find_element(By.ID,'kw').send_keys('python')
driver.find_element(By.ID,'su').click()
time.sleep(5)
driver.close()

示例2:

el_list:list= driver.find_elements(By.XPATH,"/html/body/div[6]/div[2]/ul/li/div[2]/h2/a")for el in el_list:print(el.text)print(el.get_attribute('href'))

标签页(窗口)切换

我们在使用浏览器的时候,会自动转到新的标签页,但selenium不会这样,我们需要进行操作来实现

利用窗口句柄切(指向标签页对象的标识)换到句柄指向的标签页

driver.get("url")
time.sleep(3)print(driver.current_url)#获取当前页面的urlprint(driver.window_handles)#获取当前所有存在的窗口句柄,多个句柄以列表方式存储
driver.find_element(By.XPATH,"/html/body/div[6]/div[2]/ul/li[1]/div[2]/h2").click()print(driver.current_url)print(driver.window_handles)
time.sleep(3)
driver.switch_to.window(driver.window_handles[-1])#切换至新窗口print(driver.current_url)
time.sleep(3)
driver.close()#关闭当前窗口
driver.switch_to.window(driver.window_handles[0])#切换至原窗口print(driver.current_url)

iframe切换

<iframesrc="1.html"id="hogwarts_id"name="hogwarts_name"></iframe>

实现:

# index:传入整型的参数,从 0 开始,这里的 0 就是第一个 frame
driver.switch_to.frame(0)#id:iframe 的 id
driver.switch_to.frame("hogwarts_id")#name: iframe 的 name
driver.switch_to.frame("hogwarts_name")#WebElement: 传入 `selenium.webelement` 对象
driver.switch_to.frame(driver.find_element(By.TAG_NAME,"iframe"))

在切换页面之后,如果还想操作原页面,则可以使用:

driver.switch_to.default_content()

嵌套多层iframe的切换:

<html><iframesrc="a.html"id="frame1"><iframesrc="b.html"id="frame2">
                <input id="kw" / >
            </iframe></iframe></html>

多层嵌套的情况下,如果要从主界面切换到第二层iframe,则需要一层一层的切换进去,即先切换到frame1,再切换到frame2,而不是直接切换进入frame2

driver.switch_to.frame("frame1")
driver.switch_to.frame("frame2")

selenium还提供了一个切换到父frame的方法,比如我们切换到frame2之后,要想切换到frame1操作,则不需要先切回主界面再切换到frame,而是使用如下方法:

driver.switch_to.parent_frame()

需要注意的是,如果当前已经是主页面,则使用此方法无效

cookies操作

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

chrome_options = Options()
chrome_options.page_load_strategy ='eager'
service = Service('chromedriver.exe路径')

driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://www.baidu.com")#print(driver.get_cookies())#转换为字典格式
cookies ={}for data in driver.get_cookies():
    cookies[data['name']]= data['value']#字典推导式
cookies1={data['name']: data['value']for data in driver.get_cookies()}print(cookies)print(cookies1)
driver.delete_cookie('CookieName')#删除一条cookie
driver.delete_all_cookies()#删除所有cookie

页面等待

强制等待

time.sleep()

缺点:不智能:设置的时间短,元素还没有加载出来;设置的时间长,则会浪费时间

隐式等待

隐式等待针对的是元素定位(设置一次,所有元素定位都会按照设定),隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步;如果在设置的时间内没有定位成功,则会报超时加载

#隐式等待from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

chrome_options = Options()
chrome_options.page_load_strategy ='eager'
service = Service('chromedriver.exe路径')

driver = webdriver.Chrome(service=service, options=chrome_options)
driver.implicitly_wait(5)#设置隐式等待时间为5秒
driver.get("https://www.baidu.com")
driver.find_element(By.ID,'kkww')#5秒钟内定位不到元素,报错

显式等待

明确等待某一个元素

每经过多少秒就查看一次等待条件是否达成,如果达成就停止等待,继续执行后续代码;如果没有达成就继续等待直到超过规定的时间后报超时异常

多用于软件测试,想要了解请自行查找

Chrome无界面模式

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

chrome_options = Options()
chrome_options.page_load_strategy ='eager'
service = Service('chromedriver.exe路径')
chrome_options.add_argument("--headless")#添加开启无界面模式的命令
chrome_options.add_argument("--disable-gpu")#添加开启禁用gpu的命令

driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://www.baidu.com")
driver.save_screenshot('baidu.png')

配置代理:

chrome_options.add_argument("--proxy-server=http://113.254.44.242:8382") 

注意:更换ip代理必须重启浏览器

配饰UserAgent:``chrome_options.add_argument(“–user-agent=XXXX”)`

案例

【Python爬虫】案例_斗鱼

标签: python 爬虫 selenium

本文转载自: https://blog.csdn.net/qq_45951891/article/details/139156088
版权归原作者 Root_Smile 所有, 如有侵权,请联系我们删除。

“【Python爬虫】Selenium使用”的评论:

还没有评论