Selenium模块

Selenium模块前戏

Ajax引入

"""
在使用requests抓取页面时,得到的结果可能会和在浏览器中看到的不一样,在浏览器中正常显示的页面数据,使用requests却没有得到结果

因为requests获取的都是原始页面HTML文档,而浏览器中的页面则是通过javascript数据处理后生成的结果

我们通过浏览器的开发者模式,看不到页面完整的数据?
一般情况下,这些数据都是通过Ajax来加载的,JavaScript在后台调用这些Ajax数据接口得到数据后,再把数据进行解析并渲染呈现出来,得到最终的页面

******************************************************************************
你会发现在用鼠标向下滚动的过程中,下面会刷新数据,就是发送一次Ajax请求来获取下面的数据,这也就是Ajax的强大之处***异步提交,局部更新***
******************************************************************************

这样对我们爬取数据造成了阻碍,这时就有了Selenium 是一个自动化测试工具,利用它我们可以驱动浏览器执行特定的动作,如点击、下拉等操作。对于一些 JavaScript 渲染的页面来说,这种抓取方式非常有效。
"""

Selenium安装

pip3 install selenium

ChromeDriver驱动安装

"""
只有安装 ChromeDriver配合selenium,才能驱动 Chrome 浏览器完成相应的操作。下面我们来介绍下怎样安装 ChromeDriver。
"""
# 1)查看Chrome浏览器的版本号,下载版本号一样的ChromeDriver驱动,不然驱动不了你的浏览器

# 2) 下载ChromeDriver驱动链接:
https://chromedriver.storage.googleapis.com/index.html
    
# 3)配置环境变量
	# 3.1) 第一种方式
    """
    把chromedriver.exe放到了python安装目录的scripts文件夹下,然后去配置环境变量
     
    注意:这个可能在pycharm中使用找不到配置环境变量的路径,那就选择第二种方式
    """
	# 3.2) 第二种方式
    """
   	把chromedriver.exe放到python安装目录下,然后去配置环境变量,我测试的该方式有效
    """
   
# 4)检验安装
"""
在cmd窗口中输入chromedriver返回数据:
Starting ChromeDriver 96.0.4664.18 (b8887b3d1742adb0873f871edc1d8d8c1d46bb96-refs/branch-heads/4664@{#236}) on port 9515
Only local connections are allowed.

证明安装成功
"""


# 5)可能出现的情况
"""
运行之后,如果弹出一个空白的 Chrome 浏览器,则证明所有的配置都没有问题。如果没有弹出,请检查之前的每一步配置。

如果弹出后闪退,则可能是 ChromeDriver 版本和 Chrome 版本不兼容,请更换 ChromeDriver 版本。
"""

selenium的简单使用

import time
from selenium import webdriver

# 通过指定chromedriver的路径来实例化driver对象。
# chromedriver已经添加环境变量
driver = webdriver.Chrome()

# 控制浏览器访问url地址
driver.get("https://www.baidu.com/")

# 在百度搜索框中搜索'python'
driver.find_element_by_id('kw').send_keys('python') # 定位id属性值是'kw'的标签,并向其中输入字符串'python'
# 点击'百度搜索'
driver.find_element_by_id('su').click() # 定位id属性值是su的标签,并点击,click函数作用是:触发标签的js的click事件

time.sleep(6)
# 退出浏览器
driver.quit()  # 如果不退出浏览器会有进程没有关闭,占资源

selenium数据提取

1、driver对象的常用属性和方法

  1. driver.page_source 当前标签页浏览器渲染之后的网页源代码
  2. driver.current_url 当前标签页的url
  3. driver.close() 关闭当前标签页,如果只有一个标签页则关闭整个浏览器
  4. driver.quit() 关闭浏览器
  5. driver.forward() 页面前进
  6. driver.back() 页面后退
  7. driver.screen_shot(img_name) 页面截图

2、driver对象定位标签元素获取标签对象的方法

find_element_by_id                         (返回一个元素)
find_element(s)_by_class_name             (根据类名获取元素列表)
find_element(s)_by_name                 (根据标签的name属性值返回包含标签对象元素的列表)
find_element(s)_by_xpath                 (返回一个包含元素的列表)
find_element(s)_by_link_text             (根据连接文本获取元素列表)
find_element(s)_by_partial_link_text     (根据链接包含的文本获取元素列表)
find_element(s)_by_tag_name             (根据标签名获取元素列表)
find_element(s)_by_css_selector         (根据css选择器来获取元素列表)

"""
find_element和find_elements的区别:
    多了个s就返回列表,没有s就返回匹配到的第一个标签对象
    find_element匹配不到就抛出异常,find_elements匹配不到就返回空列表
by_link_text和by_partial_link_tex的区别:全部文本和包含某个文本
"""

3、标签对象提取文本内容和属性值

element.click()  # 对定位到的标签对象进行点击操作
element.send_keys(data)  # 对定位到的标签对象输入数据
element.tetx # 通过定位获取标签对象的文本内容
element.get_attribute('属性名') # 获取属性名的内容

selenium的其他使用方法

1、selenium标签的切换

# 当selenium控制浏览器打开多个标签页时,如何控制浏览器在不同的标签页中切换?分两步:
    1.获取所有标签页的窗口句柄
    2.利用窗口句柄(指向标签页对象的标识)字切换到句柄指向的标签页

# 具体的方法
"""
1. 获取当前所有的标签页的句柄构成列表
current_windows = driver.window_handles

2.根据标签页句柄列表索引下标进行切换
driver.swith_to.window(current_windows[0])
"""

2、switch_to切换frame标签

"""
iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的

解决思路:
1.切换到定位的frame标签嵌套的页面中
    login_frame = driver.find_element_by_id('login_frame') # 根据id定位 frame元素
    driver.switch_to.frame(login_frame) # 转向到该frame中
    
2.利用切换标签页的方式切出frame标签
    windows = driver.window_handles
    driver.switch_to.window(windows[0])
"""

3、获取cookie

# 1) 获取cookie
	"""
	driver.get_cookies()返回列表,其中包含的是完整的cookie信息!不光有name、value,还有		domain等cookie其他维度的信息。
	"""
    # 获取当前标签页的全部cookie信息
    print(driver.get_cookies())
    # 把cookie转化为字典
    cookies_dict = {cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}
   
# 2) 删除cookie
	# 删除一条cookie
    driver.delete_cookie('CookieName')
    # 删除所有的cookie
    driver.delete_all_cookies
    

4、selenium控制浏览器执行js代码

js = 'window.scrollTo(0,document.body.scrollHeight)' # js语句
driver.execute_script(js) # 执行js的方法

5、页面等待

# 1)强制等待(了解)
"""
1.其实就是time.sleep()
2.缺点时不智能,设置的时间太短,元素还没有加载出来;设置时间太长,则会浪费时间
"""

# 2)隐式等待
"""
1.隐式等待针对的是元素定位,隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步
2.在设置的时间内没有定位成功,则会报超时加载
"""
driver.implicitly_wait(10) # 隐式等待,最长等20秒  

# 3)显示等待(了解)
"""
1.每经过多少秒就查看一次等待条件是否达成,如果达成就停止等待,继续执行后续代码
2.如果没有达成就继续等待直到超过规定的时间后,报超时异常
"""
# 显式等待
WebDriverWait(driver, 20, 0.5).until(
    EC.presence_of_element_located((By.LINK_TEXT, '好123')))  
# 参数20表示最长等待20秒
# 参数0.5表示0.5秒检查一次规定的标签是否存在
# EC.presence_of_element_located((By.LINK_TEXT, '好123')) 表示通过链接文本内容定位标签
# 每0.5秒一次检查,通过链接文本内容定位标签是否存在,如果存在就向下继续执行;如果不存在,直到20秒上限就抛出异常

# 4)手动实现页面等待(重点)
"""
解决场景:"页面需要滑动才能触发ajax异步加载"的场景

原理:
	1.利用强制等待和显示等待的思路来手动实现
	2.不停的判断或有次数限制的判断某一个标签对象是否加载完毕(是否存在)
"""
import time
from selenium import webdriver
driver = webdriver.Chrome()

driver.get('https://www.taobao.com/')
time.sleep(1)

for i in range(10):
    i += 1
    try:
        time.sleep(3)
        element = driver.find_element_by_xpath('//div[@class="shop-inner"]/h3[1]/a')
        print(element.get_attribute('href'))
        break
    except:
        js = 'window.scrollTo(0, {})'.format(i*500) # js语句
        driver.execute_script(js) # 执行js的方法
driver.quit()

6.selenium开启无界面模式(又称之为无头模式)

from selenium import webdriver

options = webdriver.ChromeOptions() # 创建一个配置对象
options.add_argument("--headless") # 开启无界面模式
options.add_argument("--disable-gpu") # 禁用gpu

driver = webdriver.Chrome(chrome_options=options) # 实例化带有配置的driver对象

7、selenium使用代理ip

options = webdriver.ChromeOptions() # 创建一个配置对象
options.add_argument('--proxy-server=http://202.20.16.82:9527') # 使用代理ip

driver = webdriver.Chrome('./chromedriver',chrome_options=options) # 实例化带有配置的driver对象

8.selenium替换user-agent

options = webdriver.ChromeOptions() # 创建一个配置对象
options.add_argument('--user-agent=Mozilla/5.0 HAHA') # 替换User-Agent

driver = webdriver.Chrome('./chromedriver', chrome_options=options) # 实例化带有匹配对象的driver对象
posted @ 2022-02-14 22:13  程序员少帅  阅读(66)  评论(0)    收藏  举报