爬虫之selenium

import time

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

# 设置访问结束浏览器不自动关闭
# 1、创建 Edge 选项对象
edge_options = Options()
# 2、添加 experimental_option 'detach' 设置为 True 以防止浏览器关闭
edge_options.add_experimental_option("detach", True)
# 2、设置为headless模式,避免打开浏览器窗口(可选)
# edge_options.add_argument('--headless')

# chrome_path = 'D:\安装包\python\edgedriver125\msedgedriver.exe'
# edge_path = 'D:\安装包\python\edgedriver125\msedgedriver.exe'


driver = webdriver.Edge(options=edge_options)
# browser = webdriver.Chrome()   # 这种是配置好了浏览器驱动的环境变量
# driver = webdriver.Chrome(service=Service(chrome_path), options=Options())  # 这种是传入浏览器驱动的方式

# 访问网址
driver.get(r'https://www.baidu.com/')

# # 获取标题
# print(browser.title)
# # 获取网页源码
# print(browser.page_source)

# 截图
# screen_binary = driver.get_screenshot_as_png()
# with open('baidu.png', 'wb') as fp:
#     fp.write(screen_binary)

# driver.get_screenshot_as_file('百度.png')

# 刷新页面
# try:
#     driver.refresh()
#     print('刷新页面')
# except Exception as e:
#     print('页面刷新失败')


# 前进后退
# time.sleep(2)
# driver.get('https://www.taobao.com')
# time.sleep(2)
# driver.back()
# print('后退到百度页面')
# time.sleep(2)
# driver.forward()
# print('前进到淘宝页面')

# 定位元素
"""
1、ID定位 ,通过元素的 id 属性来定位,如果 id 是唯一的,这是最快且最可靠的选择。
find_element(By.ID, "element_id")

2、Name定位,通过元素的 name 属性定位。适用于表单元素如 input、textarea 等。
find_element(By.NAME, "element_name")

3、Class Name定位,通过元素的 class 名称定位。注意,如果有多个元素具有相同的类名,这将返回第一个匹配项。
 find_element(By.CLASS_NAME, "class_name")

4、Tag Name定位,直接通过HTML标签名称来定位元素。如果页面中有多个相同标签,只返回第一个。
find_element(By.TAG_NAME, "tag_name")

5、Link Text定位,用于定位链接元素(<a> 标签),基于链接的完整文本内容。
 find_element(By.LINK_TEXT, "link_text")

6、Partial Link Text定位,同样用于定位链接,但允许使用链接文本的部分内容进行匹配。
 find_element(By.PARTIAL_LINK_TEXT, "partial_text")

7、XPath定位,使用XPath表达式进行复杂定位。XPath是一种强大的语言,可以定位页面上的任何元素,非常灵活但可能较慢。
 find_element(By.XPATH, "xpath_expression")

8、CSS Selector定位,通过CSS选择器定位元素,效率高且易于编写,特别是在处理复杂的页面布局时。
 find_element(By.CSS_SELECTOR, "css_selector")
"""
# element_kw = driver.find_element(By.ID, 'kw')
# time.sleep(2)
# element_kw.send_keys('python教程')
# time.sleep(2)
# # element_kw.click()


# 获取属性
"""
1、get_attribute()函数获取标签属性
2、text属性获取文本,单个标签直接.text即可,多个标签需要遍历他们分别获取每个文本

3、获取其他属性
除了属性和文本值外,还有id、位置、标签名和大小等属性:
.id
.location
.tag_name
.size
"""
#  <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
# element = driver.find_element(By.ID, 'kw')
# print(element.get_attribute('class'))  # s_ipt
# print(element.id)   # f.6AF50D6E0B217AB7E56A8892DA97A93D.d.2F12DB1391A285919CB96F2FBF7115EB.e.5
# print(element.tag_name)  # input
# print(element.size)    # {'height': 44, 'width': 550}
# print(element.location)   # {'x': 298, 'y': 188}


# 页面交互操作
"""
页面交互就是在浏览器的各种操作,比如上面演示过的输入文本、点击链接等等,还有像清除文本、回车确认、单选框与多选框选中等。
send_keys()  向input框中输入内容
click() 点击
clear()  清除文本,与send_keys()相反
submit()  表单的提交动作,也是点击的一种
"""
# send_keys and submit()
# element_kw = driver.find_element(By.ID, 'kw')
# element_kw.send_keys('python教程')
# time.sleep(2)
# element_kw.submit()

# click()
# element = driver.find_element(By.XPATH, '//div[@id="s-top-left"]/a[@href="http://news.baidu.com"]')
# element = driver.find_element(By.LINK_TEXT, '新闻')
# time.sleep(2)
# element.click()


# 多窗口切换
"""
比如打开页面之后在该页面点击一个超链接打开一个新窗口,不同选项卡之间的切换以及不同浏览器窗口之间的切换操作等等。
switch_to.window(handler)
这个方法用于切换到已经打开的窗口。你需要提供窗口的句柄(handle)作为参数。

switch_to.new_window()
引入于 Selenium 4.0,这个方法用于直接打开一个新类型的窗口(默认是新建一个标签页),并自动切换到新打开的窗口。你需要提供窗口类型作为参数,可选值为 'tab' 或 'window'。
使用场景:当你需要从当前窗口打开一个新的窗口或标签页,并立即切换到新打开的页面时,使用此方法会更直接、方便.
eg:
driver.switch_to.new_window('tab')  # 打开一个新标签页并切换到它
或者
driver.switch_to.new_window('window')  # 打开一个新窗口并切换到它
driver.get('https://www.example.com')
"""
# element = driver.find_element(By.LINK_TEXT, '新闻')
# element.click()
# # 此时,浏览器中就有了两个窗口。要在这两个窗口之间切换,可以按照以下步骤操作:
# # 1、获取所有窗口的句柄(handle):
# handler = driver.window_handles
# # driver.current_window_handle   # 获取当前窗口的句柄
# # print(handler)   # ['C2AE96A92EAC926657E357BBEC7F302B', 'B7B5D22DC16516D4D319A3FC2A60CD90']
# # 2、切换到特定窗口。window_handles返回的是一个列表,其中第一个元素通常是初始窗口,
# # 之后的元素对应之后打开的窗口。你可以通过索引来选择要切换到的窗口
# time.sleep(4)
# driver.switch_to.window(handler[0])  # 此时就切换到了初始的百度页面窗口


# 模拟鼠标操作
"""
from selenium.webdriver.common.action_chains import ActionChains

1、左键
这个其实就是页面交互操作中的点击click()操作。
2、右键
context_click()
3、双击
double_click()
4、拖拽
drag_and_drop(source,target),拖拽操作开始位置和结束位置需要被指定,这个常用于滑块类验证码的操作之类。
5、悬停
move_to_element()  # 在元素的中心悬停

move_to_element_with_offset(element, xoffset, yoffset) 函数主要用于模拟鼠标悬停操作,但它允许你不仅仅悬停在元素的中心位置,
而是可以在该元素的任意偏移位置上进行悬停。
参数解释:
element:这是你要悬停目标元素的WebElement对象。
xoffset 和 yoffset:分别表示相对于目标元素左上角的水平和垂直偏移量。这两个值可以是正数也可以是负数,
正数表示向右或向下移动,负数则表示向左或向上移动。
6、进度条滚动
scroll(0,100)  # 参数分别代表左右滚动和上下滚动的像素值,正数向下向右滚动
"""

# 右键
# element = driver.find_element(By.LINK_TEXT, '新闻')
# # 创建ActionChains实例
# action = ActionChains(driver)
# # 对元素执行右键点击操作
# # context_click()方法用于模拟右键点击, perform()方法真正执行鼠标操作
# # 当你使用ActionChains来构建一系列的用户交互动作(如鼠标移动、点击、拖拽等)时,这些动作并不会立即执行,
# # 而是被存储在ActionChains对象中。一旦调用了perform()方法,所有之前通过ActionChains对象定义的动作将会按照顺序依次执行。
# action.context_click(element).perform()
# # 如果需要进一步操作右键菜单中的选项,可能需要依赖于JavaScript模拟键盘操作或直接执行JavaScript代码,
# # 因为Selenium本身并不直接支持操作浏览器的右键菜单选项。

# 双击
# action.double_click(element).perform()

# 悬停
# action.move_to_element(element).perform()

# 滚动进度条
element_kw = driver.find_element(By.ID, 'kw')
element_kw.send_keys('python教程')
time.sleep(2)
element_kw.send_keys(Keys.ENTER)
time.sleep(2)
# action = ActionChains(driver)
# 开始滚动
# 下面这两个是指定滚动多少像素
# action.scroll_by_amount(0, 1000).perform()
# driver.execute_script("window.scrollBy(0, 1000);")  # 水平0,垂直向下200像素

# 下面这个是直接滚动到底部
# driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

# 下面这个是边滚动边加载到最底部
# 如果想模拟用户缓慢滚动的行为,可以通过循环逐步增加滚动距离来实现
# total_height = driver.execute_script("return document.body.scrollHeight")
# print('total_height是:', total_height)  # 4532px
# i = 1
# while True:
#     # 每次滚动1000px
#     driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
#     print(f'这是第{i}次滚动')
#
#     # 计算新的页面高度
#     new_height = driver.execute_script("return document.body.scrollHeight")
#     print(new_height)
#     i += 1
#
#     # 等待
#     time.sleep(1)  # 注意:最好使用显式等待替换固定延时
#
#     # 如果页面高度不再变化,说明已经滚动到底部,退出循环
#     if new_height == total_height:
#         break
#     else:
#         total_height = new_height


# 模拟键盘操作
"""
selenium中的Keys()类提供了大部分的键盘操作方法,通过send_keys()方法来模拟键盘上的按键。
from selenium.webdriver.common.keys import Keys
常见的键盘操作:
send_keys(Keys.BACK_SPACE):删除键(BackSpace)
send_keys(Keys.SPACE):空格键(Space)
send_keys(Keys.TAB):制表键(TAB)
send_keys(Keys.ESCAPE):回退键(ESCAPE)
send_keys(Keys.ENTER):回车键(ENTER)
send_keys(Keys.CONTRL,'a'):全选(Ctrl+A)
send_keys(Keys.CONTRL,'c'):复制(Ctrl+C)
send_keys(Keys.CONTRL,'x'):剪切(Ctrl+X)
send_keys(Keys.CONTRL,'v'):粘贴(Ctrl+V)
send_keys(Keys.F1):键盘F1
.....
send_keys(Keys.F12):键盘F12

定位需要操作的元素,然后操作即可!
"""


# 等待
"""
1、延时等待
如果遇到使用ajax加载的网页,页面元素可能不是同时加载出来的,这个时候尝试在get方法执行完成时获取网页源代码
可能并非浏览器完全加载完成的页面。所以,这种情况下需要设置延时等待一定时间,确保全部节点都加载出来。

2、强制等待
就很简单了,直接time.sleep(n)强制等待n秒。

3、隐式等待
driver.implicitly_wait(3)
Selenium 会等待指定的最长时间,不断地尝试查找元素,一旦找到元素就可以立即继续执行,无需等待剩余的全部时间。
需要注意的是,implicitly_wait() 只需要在WebDriver实例化后设置一次,它会影响后面所有的查找操作。
而且,一旦设置了隐式等待时间,这个时间会应用于整个WebDriver实例的生命周期内,
直到你关闭这个WebDriver实例或者重新设置这个值。对于需要快速响应的场景或特定操作,
可能需要结合显式等待(WebDriverWait)来实现更精确的控制。

4、 显式等待
使用显示等待需要导入WebDriverWait类和预期条件(Expected Conditions)模块
设置一个等待时间和一个条件,在规定时间内,每隔一段时间查看下条件是否成立,
如果成立那么程序就继续执行,否则就抛出一个超时异常。

eg:
# 初始化浏览器驱动
driver = webdriver.Chrome()

# 打开一个网页
driver.get("http://www.example.com")

# 使用显示等待,等待某个元素出现,最多等待10秒
# 设置判断条件:等待id='kw'的元素加载完成
try:
    element = WebDriverWait(driver, 10).until(
        input_element = wait.until(EC.presence_of_element_located((By.ID, 'kw')))
    )
    # 执行找到元素后的操作
    print("元素找到了!")
    # 在input框输入搜索词
    input_element.send_keys('Python')
finally:
    # 确保浏览器关闭
    driver.quit()



预期条件(Expected Conditions)常用方法:
presence_of_element_located(locator): 等待某个元素出现在DOM中,并且是可被定位的。
visibility_of_element_located(locator): 等待某个元素不仅是可定位的,而且还要可见(displayed)。
element_to_be_clickable(locator): 等待某个元素变为可点击状态。
text_to_be_present_in_element(locator, text): 等待某个元素的文本包含指定的文本内容。
url_to_be(url): 等待当前页面的URL变为指定的URL。




5、WebDriverWait的参数说明:
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
driver: 浏览器驱动对象
timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
poll_frequency: 每次检测的间隔时间,默认是0.5秒
ignored_exceptions:超时后的异常信息,默认情况下抛出NoSuchElementException异常

until(method,message='')
method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False
message: 如果超时,抛出TimeoutException,将message传入异常

until_not(method,message='')
until_not 与until相反,until是当某元素出现或什么条件成立则继续执行,until_not是当某元素消失或什么条件不成立则继续执行,参数也相同。
"""



posted @ 2024-08-23 17:36  有形无形  阅读(53)  评论(0)    收藏  举报