爬虫之Selenium

目录

基本用法

查找节点

查找单个节点

查找多个节点

节点交互

点击

 模拟鼠标移动

拖动节点

执行JavaScript代码

获取节点信息

管理cookie

改变节点属性值


基本用法

运行本例之前,需要将chromedriver或chromedriver.exe文件放在当前目录的webdriver子目录中。

运行程序,会立刻启动Chrome浏览器,并打开京东首页,然后在京东首页上方的搜索框中输入“Python从菜鸟到高手”

WebDriverWait类,该类是为了在执行的过程中等待一段时间,这里设置为4秒。、

按Enter键后,并不一定马上显示搜索结果,需要有一定的延长,但python程序不会等待搜索结果出来再往下执行,python程序会一直执行下去,所以如果不等待一定时间,就会造成python程序已经运行到处理搜索结果页面的位置时,搜索结果页面还没显示出来。所以就需要使用WebDriverWait类的until方法判断结果页面是否显示完成。

判断搜索结果页面是否显示完全:如果搜索页面加载完成,页面中所有的节点肯定已经加载完成了,所以只要随便获取页面中的某个节点,如果获取成功,说明已经加载完成。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver')
try:
    # 打开京东
    browser.get('https://www.jd.com/')
    # 根据id属性的值查找搜索框
    input1=browser.find_element(By.ID,'key')
    # 使用send_keys方法向搜索框输入"python从菜鸟到高明"文本
    input1.send_keys('python从菜鸟到高明')
    # 使用send_keys方法模拟按下<Enter>键
    input1.send_keys(Keys.ENTER)
    # 创建WebDriverWait对象,设置最长等待时间(4秒)
    wait=WebDriverWait(browser,4)
    # 等待搜索页面显示(通过查找id为goodsList的节点判断搜索页面是否显示)
    wait.until(ec.presence_of_all_elements_located((By.ID,'J_goodsList')))
    # 显示搜索页面的标题
    print(browser.title)
    # 显示搜索页面的URL
    print(browser.current_url)
    # 显示搜索页面的代码
    print(browser.page_source)
    # 关闭浏览器
    browser.close()
except Exception as e:
    print(e)
    browser.close()

查找节点

查找单个节点

看源码可知,browser.find_element方法支持(id,name,class_name元素定位)

    def find_element(self, by=By.ID, value: Optional[str] = None)
        if by == By.ID:
            by = By.CSS_SELECTOR
            value = '[id="%s"]' % value
        elif by == By.CLASS_NAME:
            by = By.CSS_SELECTOR
            value = ".%s" % value
        elif by == By.NAME:
            by = By.CSS_SELECTOR
            value = '[name="%s"]' % value

查找多个节点

方法同上
区别:browser.find_elements返回一个列表,包含符合条件的所有节点,如果没有符合条件的节点,就会返回空列表(长度为0的列表)

节点交互

点击

click()

 模拟鼠标移动

使用actions.move_to_element方法,以下为ActionChains类常用方法

1、perform():执行所有ActionChains中存储的行为

2、context_click():右击

3、double_click():双击

4、move_to_element():悬停

5、drag_and_drop(source, target):拖动

最后都必须调用perform方法才能生效

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
import time
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver')
try:
    browser.get('https://www.jd.com/')
    # 创建ActionChains对象
    actions=ActionChains(browser)
    # 通过CSS选择器查找所有class属性值为cate_menu_item的li节点,每一个li节点是一个二级导航菜单
    li_list=browser.find_elements(By.CSS_SELECTOR,'.cate_menu_item')
    for li in li_list:
        actions.move_to_element(li).perform()
        time.sleep(1)
except Exception as e:
    print(e)
    browser.close()

拖动节点

使用drag_and_drop方法拖到节点

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver')
try:
    browser.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
    # 切换到id属性值为iframeResult的iframe节点上
    browser.switch_to.frame('iframeResult')
    # 使用CSS选择器获取id属性值为draggable的拖动节点
    sourse=browser.find_element(By.CSS_SELECTOR,'#draggable')
    # 使用CSS选择器获取id属性值为droppable的接收节点
    target = browser.find_element(By.CSS_SELECTOR, '#droppable')
    # 创建ActionChains对象
    actions=ActionChains(browser)
    # 调用drag_and_drop方法拖动节点
    actions.drag_and_drop(sourse,target)
    # 调用perfrom方法让拖动生效
    actions.perform()
except Exception as e:
    print(e)
    browser.close()

执行JavaScript代码

有些操作Selenium没有提供相应的API,例如下拉页面
可以使用Selenium得execute_script方法直接运行JavaScript代码,便于扩展Selenium功能

from selenium import webdriver
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver')
browser.get('https://www.jd.com/')
# 将京东商城首页滚动到最底端
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 弹出对话框
browser.execute_async_script('alert("已经到最底端")')
time.sleep(10)

获取节点信息

如节点位置(相当于页面绝对坐标)、节点名称、节点尺寸(高和宽)、节点属性值

from selenium import webdriver
from selenium.webdriver.common.by import By
options=webdriver.ChromeOptions()
# 添加参数,不然Chrome浏览器显示,只在后台运行
options.add_argument('headless')
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver',chrome_options=options)
browser.get('https://www.jd.com/')
# 查找页面中id属性值为navitems-group1的第1个节点(是一个ul节点)
ul=browser.find_element(By.ID,'navitems-group1')
# 输出节点的文本
print(ul.text)
# 输出节点内部使用的id,注意,不是id属性值
print('id','=',ul.id)
# 输出节点的位置(相对于页面的绝对坐标)
print('location','=',ul.location)
# 输出节点的名称
print('tag_name','=',ul.tag_name)
# 输出节点的尺寸
print('size','=',ul.size)
# 搜索该节点内的所有名为li的节点
li_list=ul.find_elements(By.TAG_NAME,'li')
for li in li_list:
    # 输出li的类型
    print(type(li))
    # 输出li节点的文本和class属性值,如果属性没找到,返回None
    print('<',li.text,'>','class=',li.get_attribute('class'))
    # 查找li节点内名为a的子节点
    a=li.find_element(By.TAG_NAME,'a')
    # 输出a节点的href属性值
    print('href','=',a.get_attribute('class'))
browser.close()

基于selenium的爬虫通常会加上headless选项、这样爬取数据过程就不会弹出Chrome浏览器,但是他会在后台进行页面加载、数据提取等工作

管理cookie

获取cookie,添加cookie,删除cookie

from selenium import webdriver
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver')
browser.get('https://www.jd.com/')
# 获取cookie列表
print(browser.get_cookies())
# 添加新的cookie
browser.add_cookie({'name':'name','value':'jd','domain':'www.jd.com'})
print(browser.get_cookies())
# 删除所有的cookie
browser.delete_all_cookies()
print(browser.get_cookies())

改变节点属性值

selenium没有改变节点属性的API,所以要通过JavaScript代码改变
通过selenium获取的节点可以直接作为DOM使用,意味着在JavaScript代码使用查找到的节点
execute_script方法第1个参数用于指定JavaScript代码,后面的可变参数,可以为JavaScript代码传递参数。通过arguments变量获取每一个参数值,例如arguments[0]第一个参数arguments[0]第二个参数,以此类推

例子1:使用JavaScript代码改变百度搜索按钮的位置,让这个按钮多个位置移动,2秒一次

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver')
browser.get('https://www.baidu.com')
# 查找百度搜索按钮
search_button=browser.find_element(By.ID,'su')
# 定义搜索按钮可以移动的x坐标的位置
x_positions=[50,90,130,170]
# 定义搜索按钮可以移动的y坐标的位置,与x坐标列表中元素的个数要相等
y_positions=[100,120,160,90]
# 迭代位置列表,每隔2秒移动一次搜索按钮
for i in range(len(x_positions)):
    # 用于移动搜索按钮的JavaScript代码,arguments[0]就是搜索按钮对应的DOM
    js="""
    arguments[0].style.position="absolute";
    arguments[0].style.left="{}px"
    arguments[0].style.top="{}px";
    """.format(x_positions[i],y_positions[i])
    # 执行JavaScript代码,并开始移动搜索按钮
    browser.execute_script(js,search_button)
    time.sleep(2)

例子2:修改页面文本以及链接

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
browser=webdriver.Chrome('D:\chromedriver_win32\chromedriver')
browser.get('https://www.jd.com')
# 查找id属性值为navitems-group1的节点
ul=browser.find_element(By.ID,'navitems-group1')
# 查找该节点下所有名为li的子节点
li_list=ul.find_elements(By.TAG_NAME,'li')
# 查找第1个li节点中第一个名为a的子节点
a1=li_list[0].find_element(By.TAG_NAME,'a')
# 查找第2个li节点中第一个名为a的子节点
a2=li_list[1].find_element(By.TAG_NAME,'a')
# 下面的JavaScript代码用于修改上面查找到的两个a节点的文本和链接(href属性值)
js="""
arguments[0].text='Python从菜鸟到高手'
arguments[0].href='https://item.jd.com/12417265.html'
arguments[1].text='极客起源'
arguments[1].href='https://geekori.com'
"""
browser.execute_script(js,a1,a2)
time.sleep(5)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值