Selenium XPath

selenium

1、selenium是什么呢?

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法执行javaScript代码的问题。

它可以做什么呢?它可以用几行代码,控制浏览器,做出自动打开、输入、点击等操作,就像是有一个真正的用户在操作一样。

selenium允许让人去手动输入验证码,然后把剩下的操作交给机器。 而对于那些交互复杂、加密复杂的网站,selenium问题简化 ,爬动态网页如爬静态网页一样简单。

安装

pip install selenium # Windows电脑安装selenium

selenium的脚本可以控制所有常见浏览器的操作,在使用之前,需要安装浏览器的驱动。

我推荐的是Chrome浏览器,打开下面的链接,就可以下载Chrome的安装包了,Windows和Mac都有。

国内镜像网站地址:
        http://npm.taobao.org/mirrors/chromedriver/2.38/

设置浏览器引擎

下载chromed浏览器驱动:
    把下载好的chromedriver.exe放到python安装路径的scripts目录中即可,注意最新版本是2.38,并非2.9

和以前一样,使用一个新的Python库,首先要调用它。selenium有点不同,除了调用,还需要设置浏览器引擎。

#本地Chrome浏览器设置方法
from selenium import webdriver  # 从selenium库中调用webdriver库
driver_path = r'E:\chromedriver_win32\chromedriver.exe'
driver = webdriver.Chrome(executable_path=driver_path)
#设置引擎为Chrome,真实地打开一个Chrome浏览器

2、基本使用

示例一:
from selenium import webdriver  #用来驱动浏览器的
from selenium.webdriver import ActionChains #破解滑动验证码的时候用,可拖动图片
from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC        # 和下面WebDriverWait一起用的
from selenium.webdriver.support.wait import WebDriverWait   #等待页面加载某些元素
import time
try:
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com')
    wait = WebDriverWait(driver,10)
    input_tag = wait.until(EC.presence_of_element_located((By.ID,'kw')))
    input_tag.send_keys('美女')
    input_tag.send_keys(Keys.ENTER)
    time.sleep(5)

finally:
    driver.close()
示例二:

from selenium import webdriver  # 用来驱动浏览器的
from selenium.webdriver.common.by import By  # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC  # 和下面WebDriverWait一起用的
from selenium.webdriver.support.wait import WebDriverWait  # 等待页面加载某些元素
import time
option = webdriver.ChromeOptions()

# 通过add_argument为配置添加参数
# 此参数用于跳过 "正受到自动测试软件的控制"
option.add_argument('disable-infobars')

driver = webdriver.Chrome(chrome_options=option)

try:
    driver.get('https://china.nba.com/')    # 往NBA官网发送get请求
    wait = WebDriverWait(driver,10)         # 获取等待对象,可等待某个元素10秒
    game = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'nav-schedule')))
# 查找赛程标签并点击
    game.click()
    time.sleep(10)
except:
    driver.close()

3、等待元素被加载

'''
1、selenium只是模拟浏览器的行为,而浏览器解析页面是需要时间的(执行css,js),一些元素可能需要过一段时间才能加载出来,为了保证所有元素都能查到,必须等待。

2、等待的方式分两种:

    隐式等待:在browser.get('xxx')前就设置,针对所有元素有效

    显式等待:在browser.get('xxx')之后设置,只针对某个元素有效
'''
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素

browser=webdriver.Chrome()

#隐式等待:在查找所有元素时,如果尚未被加载,则等10秒
browser.implicitly_wait(10)

browser.get('https://www.baidu.com')


input_tag=browser.find_element_by_id('kw')
input_tag.send_keys('美女')
input_tag.send_keys(Keys.ENTER)

contents=browser.find_element_by_id('content_left') #没有等待环节而直接查找,找不到则会报错
print(contents)

browser.close()
 
隐式等待

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素

browser=webdriver.Chrome()
browser.get('https://www.baidu.com')


input_tag=browser.find_element_by_id('kw')
input_tag.send_keys('美女')
input_tag.send_keys(Keys.ENTER)


#显式等待:显式地等待某个元素被加载
wait=WebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,'content_left')))

contents=browser.find_element(By.CSS_SELECTOR,'#content_left')
print(contents)


browser.close()

显式等待

4、选择器

  1. 基本用法
'''
===============所有方法===================
    element是查找一个标签
    elements是查找所有标签
    
    1、find_element_by_link_text  通过链接文本去找
    2、find_element_by_id 通过id去找
    3、find_element_by_class_name
    4、find_element_by_partial_link_text
    5、find_element_by_name
    6、find_element_by_css_selector
    7、find_element_by_tag_name
'''
from selenium import webdriver
from selenium.webdriver import ActionChains
import time

option = webdriver.ChromeOptions()

option.add_argument('disable-infobars')

# 通过add_argument为配置添加参数
# 此参数用于跳过 "正受到自动测试软件的控制"
driver = webdriver.Chrome(chrome_options=option)

driver.get('https://qzone.qq.com/')
driver.implicitly_wait(10)

# 1、find_element_by_link_text  通过全局文本去找
driver.switch_to.frame('login_frame')
login_clike = driver.find_element_by_link_text('帐号密码登录').click()

# 2、find_element_by_id 通过id去找
user = driver.find_element_by_id('u')
user.send_keys('1394551891')
pwd = driver.find_element_by_id('p')
pwd.send_keys('zxczxc')

# 3、find_element_by_class_name  根据属性名查找
login = driver.find_element_by_class_name('btn').click()

# 让光标悬浮在个人中心
action = ActionChains(driver).move_to_element(driver.find_element_by_id('slideBlock')).perform()


# 4、find_element_by_partial_link_text  通过局部文本去找
login_tag = driver.find_element_by_partial_link_text('登')
login_tag.click()

# 6、find_element_by_css_selector 根据属性选择器查找
login_btn = driver.find_element_by_css_selector('.btn-login')
login_btn.click()

# 7、find_element_by_tag_name  根据标签名查找
a_s = driver.find_elements_by_tag_name('a')
    for a in a_s:
        # 打印字数超过10位的文本
        if len(a.text) > 10:
            print(a.tex

XPath

XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行查找。

在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

选区节点

表达式 描述
节点的名字 选取此节点中的所有子节点
/ 从根节点选取
// 选取当前节点文档中的任意一个节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
from selenium import webdriver

'''
<html><head>
  <base href="http://example.com/">
  <title>Example website</title>
 </head>
 <body>
  <div id="images">
   <a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>
   <a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>
   <a href="image3.html">Name: My image 3 <br><img src="image3_thumb.jpg"></a>
   <a href="image4.html">Name: My image 4 <br><img src="image4_thumb.jpg"></a>
   <a href="image5.html">Name: My image 5 <br><img src="image5_thumb.jpg"></a>
  </div>
</body></html>
'''

from selenium import webdriver
driver = webdriver.Chrome()
try:
    driver.get('https://doc.scrapy.org/en/latest/_static/selectors-sample1.html')
    driver.implicitly_wait(3)
    
    # 获取当html标签内的所有子节点
    html = driver.find_element_by_xpath('html')
    # 查找html中所有的a标签
    a_s = html.find_elements_by_tag_name('a')
    print(len(a_s))
    
    # 从根节点开始查找html元素
    html = driver.find_element_by_xpath('./html')
    print(html.tag_name)
    
    # 查找html元素子节点内的body标签,注意只能从根开始查找
    body = driver.find_element_by_xpath('html/body')
    print(body.tag_name)
    
    # 从当前文档内全局查找,找所有的img标签
    imgs = driver.find_elements_by_xpath('//img')
    for img in imgs:
        print(img.get_attribute('src'))
    
    #查找html元素下的所有a的节点
    a_tag_s = driver.find_elements_by_xpath('html//a')
    for a in a_tag_s:
        print(a.get_attribute('href'))
finally:
    driver.close()

3获取标签属性(了解)

标签属性 描述
id 标签id
tag_name 标签名
size 标签大小
location 标签高宽
from selenium import webdriver
from selenium.webdriver.common.by import By     # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait   # 等待页面加载某些元素
from time import sleep

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com/s?wd=美女')

    wait = WebDriverWait(browser,10)
    img_tag = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'op-img-address-link-imgs')))

    #获取标签属性
    print(img_tag.get_attribute('src'))

# 获取标签ID,位置,名称,大小(了解)
    print(img_tag.id)
    print(img_tag.location)
    print(img_tag.tag_name)
    print(img_tag.size)

    # 获取页面上图片长宽 大小
    print(img_tag.size['height'], img_tag.size['width'])
    print(img_tag.location['x'], img_tag.location['y'])


finally:
    browser.close()

元素交互操作

点击清除

from selenium import webdriver  #用来驱动浏览器
from selenium.webdriver.common.keys import Keys     #键盘按键操作
import time

#获取驱动浏览器配置信息对象,可对其信息进行修改
option = webdriver.ChromeOptions()
# 通过add_argument为配置添加参数
# 此参数用于跳过 "正受到自动测试软件的控制"
option.add_argument('disable-infobars')

driver = webdriver.Chrome(chrome_options=option)

try:
    driver.get('https://www.jd.com')
    driver.implicitly_wait(10)

    input_tag = driver.find_element_by_id('key')
    input_tag.send_keys('大炮')
    search_button = driver.find_element_by_class_name('button').click()
    time.sleep(1)

    #清空
    input_tag = driver.find_element_by_class_name('text')
    input_tag.clear()
    input_tag.send_keys('哇哈哈哈')
    input_tag.send_keys(Keys.ENTER)

except Exception:

    driver.close()

Action Chains

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By     #按照上面方式查找,By.ID,By.css_SELECTOR
from selenium.webdriver.common.keys import Keys     #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait       #等待页面加载某些元素
import time

driver = webdriver.Chrome()
driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
wait = WebDriverWait(driver,3)
# driver.implicitly_wait(3)     使用隐式等待

try:
    driver.switch_to.frame('iframeResult')      ##切换到iframeResult
    sourse = driver.find_element_by_id('draggable')
    target = driver.find_element_by_id('droppable')
    
    # 方式一:基于同一个动作链串行执行
    # actions = ActionChains(driver)#拿到动作链对象
    # actions.drag_and_drop(sourse,target)#把动作放到动作链中,准备串执行
    # actions.perform()
    
    # 方式二:不同的动作链,每次移动的位移都不同
    ActionChains(driver).click_and_hold(sourse).perform()
    distance = target.location['x'] - sourse.location['x']
    
    track = 0
    while track < distance:
        ActionChains(driver).move_by_offset(xoffset=2,yoffset=0).perform()
        track += 2
    
    ActionChains(driver).release().perform()
finally:
    driver.close()

在交互动作比较难实现的时候可以自己写JS(万能方法 )

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素

try:
    browser = webdriver.Chrome()
    browser.get('https://www.baidu.com')
    browser.execute_script('alert("hello world")')   #打印警告
finally:
    browser.close()

frame的切换

frame相当于一个单独的网页,在父frame里是无法直接看到字frame的元素的,必须switch_to_frame切换到该frame下,才能进一步查找

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By     #按照上面方式找,By.ID,BY.css_SELECTOR
from selenium.webdriver.common.keys import Keys     #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait       #等待页面加载元素

try:
    browser = webdriver.Chrome()
    browser.get("http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
    browser.switch_to.frame('iframeResult') #切换到id为iframeResult的farme
    tag1 = browser.find_element_by_id('droppable')
    print(tag1)

    # tag2=browser.find_element_by_id('textareaCode') #报错,在子frame里无法查看到父frame的元素
    browser.switch_to.frame()   #切回父frame,就可以查到了
    tag2 = browser.find_element_by_id('textareaCode')
    print(tag2)
except:
    browser.close()

猜你喜欢

转载自www.cnblogs.com/leiting7/p/11800005.html