Python爬虫学习笔记-第十一课(selenium下)

1. 行为链

如果在页面中的操作可能要有很多步,那么这时候可以使用鼠标行为链类ActionChains来完成。比如现在要将鼠标移动到某个元素上并进行点击操作。常见的鼠标操作有:

示例代码:

from selenium import webdriver
from selenium.webdriver import ActionChains
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 定位到输入框
inputTag = driver.find_element_by_id('kw')
# 定位百度一下按钮
buttonTag = driver.find_element_by_id('su')
# 实例化
actions = ActionChains(driver)
# 把鼠标移动到输入框里面
actions.move_to_element(inputTag)
# 输入内容
actions.send_keys_to_element(inputTag, 'Python')
time.sleep(1)
# 将鼠标移动到按钮上,并点击
actions.move_to_element(buttonTag)
actions.click()
time.sleep(1)
# 右键单击
actions.context_click()
# 提交行为链上的操作
actions.perform()
# 如果想使用buttonTag对象操作点击,必须在提交行为后
# time.sleep(1)
# buttonTag.click()

运行结果:
在这里插入图片描述
编写上述代码时的一些注意点:

  1. 通过鼠标行为链操作之前,需要先进行ActionChains类的实例化;
  2. 定义两个行为后,需要提交行为才能看到想要的效果,代码上就要调用perform()方法;
  3. 如果不通过行为链点击按钮,则需在行为链提交动作之后,才能执行点击按钮(button.click()) ;
  4. 如果通过行为链点击按钮,点击“百度一下”按钮前,需先将鼠标移动到相应的按钮标签上。

2. selenium中的cookie操作

2.1 获取cookie

复习cookie的作用:

  1. 模拟登录
  2. 反反爬

cookie中真正有用的信息是字典key为name和value的数据。以获取百度网页的cookie为例:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 获取cookie, get_cookies() 返回的是一个列表
cookies = driver.get_cookies()
for cookie in cookies:
    print(cookie)

运行结果:
在这里插入图片描述

2.2 模拟登陆QQ空间

按照正常思路,登陆QQ空间有两种方法:

  1. 向url发起post请求,需携带账号密码进行登录;
  2. 拿到cookie值进行模拟登录。

先采用简单的方法进行登陆,退出到qq空间快速登录界面,找到登陆头像对应的标签,然后对其进行点击操作即可。
在这里插入图片描述

示例代码:

url = 'https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=XXXXXX'
driver = webdriver.Chrome()
driver.get(url)
button = driver.find_element_by_class_name('face')
button.click()
time.sleep(4)

运行结果:
在这里插入图片描述
关于上述代码中的url获取方法:在快速登陆界面,刷新网页,打开开发者工具,在network中寻找即可。

接下来,获取目标URL的cookie,保存到本地(也可以不保存,这里只是为了方便显示结果)。
示例代码:

# 获取qq空间网页的cookie
qqzone_cookielist = driver.get_cookies()
# 将上述列表转化为json类型的字符串
qqzone_cookiestr = json.dumps(qqzone_cookielist)
# 将cookie保存到本地文件
with open('qqzone.json', 'w') as fobj:
    fobj.write(qqzone_cookiestr)

运行结果:
在这里插入图片描述
获取到网页的cookie后,就要验证它能不能用,通常cookie的格式如下图:
在这里插入图片描述
将获取到的cookie进行处理成能使用的格式,然后携带处理后的cookie向网页发起请求,看是否能获取网页数据。
示例代码:

# 处理cookie,转化为想要的格式
cookie_strs = [cookie['name']+'='+cookie['value'] for cookie in qqzone_cookielist]
cookie_str = '; '.join(cookie for cookie in cookie_strs)
print(cookie_str)
# 向qq空间发起请求
req_url = 'https://user.qzone.qq.com/1017210919'
req_headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
    'cookie':cookie_str
}
qqzone_res = requests.get(req_url, headers=req_headers)
# 保存网页数据到本地
with open('qqzone.html','w', encoding='utf-8') as fobj:
    fobj.write(qqzone_res.text)

运行结果:
在这里插入图片描述

3. 页面等待

3.1 基本概念

现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素能完全加载出来。如果实际⻚⾯等待时间过长,导致某个元素还没出来,但是代码却要使用该元素,那么就会抛出NullPointer的异常。
为了解决上述问题,所以 Selenium 提供了两种等待方式:

  1. 隐式等待:调用driver.implicitly_wait(10)方法。那么在获取不可用的元素之前,会先等待10秒中的时间;
  2. 显式等待,表示某个条件成立后才执行获取元素的操作。也可以在等待的时候指定最长等待时间,如果超过该时间就抛出⼀个异常。通常由selenium.webdriver.support.excepted_conditions期望的条件和selenium.webdriver.support.ui.WebDriverWait来配合完成。

3.2 隐式等待

示例代码:

from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# python提供的sleep()方法,强制性的等待
# time.sleep(5)
# selenium的隐式等待,如果能找到相应的元素,就无须等待设置的时间
driver.implicitly_wait(10)
driver.find_element_by_id('kw').send_keys('python')

运行结果:
在这里插入图片描述
隐式等待的好处是如果能在设置的等待时间内找到相应的元素,就无须等完该时间,从而继续执行接下来的代码,相比time.sleep()方法无论结果如何,都会强制等待设定的时间。但缺点也明显,即如果找不到想要的元素,它会等到设置时间结束后,再报错或者抛出异常。

3.3 显式等待

代码需求:访问12306,输入车票的起始地和目的地,并查询车票信息。
12306网页中一些关键标签的选取:
在这里插入图片描述
示例代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get('https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc')
# 显式等待
# 输入出发地
# until()方法中传递的是条件
WebDriverWait(driver, 100).until(
    EC.text_to_be_present_in_element_value((By.ID, 'fromStationText'), '上海')
)
# 输入目的地
WebDriverWait(driver, 100).until(
    EC.text_to_be_present_in_element_value((By.ID, 'toStationText'), '南京')
)
# 定位查询按钮,并进行点击
button = driver.find_element_by_id('query_ticket')
button.click()

运行结果:
在这里插入图片描述
在上述代码中:

  1. WebDriverWait()方法传递的是web驱动和最长等待时间;
  2. until()方法传递的是等待终止条件,这里写的条件是某个目标ID的元素值是否为期望值;
  3. 目前代码尚无法自动填充起始地和目的地,代码只能等待手动选择完后继续向下执行;
  4. 在点击查询按钮之前,必须完成输入起始地和目的地的动作。

一些其他的等待条件:

  • presence_of_element_located:某个元素已经加载完毕;
  • presence_of_all_elements_located:网页中所有满足条件的元素都加载完毕;
  • element_to_be_clickable:某个元素是可以点击。
    更多条件参考:http://selenium-python.readthedocs.io/waits.html

4. 操作多页面

有时候浏览器窗口中有很多子页面,这种情况下通常会有切换页面的需求。selenium提供了switch_to_window()方法来进⾏切换,具体切换到哪个页面,可以从driver.window_handles中找到。
代码需求:打开两个页面,分别为百度和豆瓣,尝试切换操作页面并打印当前页面的url。
示例代码:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.implicitly_wait(2)
# 打开新的页面
driver.execute_script('window.open("https://www.douban.com/")')
driver.implicitly_wait(2)
# 此处仍然在操作百度页面
driver.find_element_by_id('kw').send_keys('python')
# 打印当前驱动的url
print(driver.current_url)
# 切换窗口
driver.switch_to.window(driver.window_handles[1])
print(driver.current_url)
# 关闭当前驱动的url
# driver.close()
# 整个退出
# driver.quit()

运行结果:
在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值