python-lenium库详解
python-lenium库详解
吉他g调指法
Selenium 是⼀个⾃动化测试⼯具,利⽤它可以驱动浏览器执⾏特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页⾯的源代码,做到可见即可爬。对于⼀些 JavaScript 动态渲染的页⾯来说,此种抓取⽅式⾮常有效。
1.lenium库的安装
pip3 install lenium
2.lenium库的基本⽤法
1)声明浏览器对象
Selenium ⽀持⾮常多的浏览器,如 Chrome、Firefox、Edge 等,还有 Android、BlackBerry 等⼿机端的浏览器。另外,也⽀持⽆界⾯浏览器 PhantomJS,我们可以⽤如下⽅式初始化:
from lenium import webdriver
7酱
browr = webdriver.Chrome()
browr = webdriver.Firefox()
browr = webdriver.Edge()
browr = webdriver.PhantomJS()
browr = webdriver.Safari()
这样就完成了浏览器对象的初始化并将其赋值为 browr 对象。
2)访问页⾯
可以⽤ get() ⽅法来请求⽹页,参数传⼊链接 URL 即可
from lenium import webdriver
browr = webdriver.Chrome()
<('')
print(browr.page_source)
browr.clo()
运⾏后发现,弹出了 Chrome 浏览器并且⾃动访问了淘宝,然后控制台输出了淘宝页⾯的源代码,随后浏览器关闭。
3)查找结点
想要从淘宝页⾯中提取搜索框这个节点,可以发现,它的 id 是 q,name 也是 q
from lenium import webdriver
browr = webdriver.Chrome()
<('')
input_first = browr.find_element_by_id('q')
input_cond = browr.find_element_by_css_lector('#q')
input_third = browr.find_element_by_xpath('//*[@id="q"]')对焦点数
print(input_first, input_cond, input_third)
browr.clo()
运⾏结果
所有获取单个节点的⽅法:
find_element_by_id find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_lector
另外,Selenium 还提供了通⽤⽅法 find_element(),它需要传⼊两个参数:查找⽅式 By 和值。实际上,它就是 find_element_by_id()这种⽅法的通⽤函数版本,⽐如 find_element_by_id(id) 就等价于 find_element(By.ID, id),⼆者得到的结果完全⼀致。
from lenium import webdriver
from by import By
browr = webdriver.Chrome()
<('')
input_first = browr.find_element(By.ID,'q')
print(input_first)
browr.clo()
多个节点
如果查找的⽬标在⽹页中只有⼀个,那么完全可以⽤ find_element() ⽅法。如果要查找所有满⾜条件的节点,需要⽤ find_elements() 这样的⽅法。注意,在这个⽅法的名称中,element 多了⼀个 s。
要查找淘宝左侧导航条的所有条⽬
from lenium import webdriver
browr = webdriver.Chrome()
<('')
lis = browr.find_elements_by_css_lector('.rvice-bd li')
print(lis)
browr.clo()
所有获取多个节点的⽅法:
find_elements_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_lector
我们也可以直接⽤ find_elements() ⽅法来选择
lis = browr.find_elements(By.CSS_SELECTOR,'.rvice-bd li')
4)节点交互
Selenium 可以驱动浏览器来执⾏⼀些操作,也就是说可以让浏览器模拟执⾏⼀些动作。⽐较常见的⽤法有:输⼊⽂字时⽤ nd_keys ⽅法,清空⽂字时⽤ clear ⽅法,点击按钮时⽤ click ⽅法。
from lenium import webdriver
import time
browr = webdriver.Chrome()
<('')
input=browr.find_element_by_id('q')
input.nd_keys('iphone')
time.sleep(1)
input.clear()
input.nd_keys('ipad')
button=browr.find_element_by_class_name('btn-arch')
button.click()
这⾥⾸先驱动浏览器打开淘宝,然后⽤ find_element_by_id() ⽅法获取输⼊框,然后⽤ nd_keys()
⽅法输⼊ iPhone ⽂字,等待⼀秒后⽤ clear() ⽅法清空输⼊框,再次调⽤ nd_keys() ⽅法输⼊ iPad ⽂字,之后再⽤ find_element_by_class_name() ⽅法获取搜索按钮,最后调⽤ click() ⽅法完成搜索动作。
5)动作链
⼀些交互动作都是针对某个节点执⾏的。⽐如,对于输⼊框,我们就调⽤它的输⼊⽂字和清空⽂字⽅法;对于按钮,就调⽤它的点击⽅法。还有另外⼀些操作,它们没有特定的执⾏对象,⽐如⿏标拖曳、键盘按键等,这些动作⽤另⼀种⽅式来执⾏,那就是动作链。
from lenium import webdriver
from lenium.webdriver import ActionChains
browr = webdriver.Chrome()
url ='/try/try.php?filename=jqueryui-api-droppable'
<(url)
browr.switch_to.frame('iframeResult')
source = browr.find_element_by_css_lector('#draggable')
target = browr.find_element_by_css_lector('#droppable')
actions = ActionChains(browr)
actions.drag_and_drop(source, target)
actions.perform()
打开⽹页中的⼀个拖曳实例,然后依次选中要拖曳的节点和拖曳到的⽬标节点,接着声明 ActionChains 对象并将其赋值为 actions 变量,然后通过调⽤ actions 变量的 drag_and_drop() ⽅法,再调⽤ perform() ⽅法执⾏动作,此时就完成了拖曳操作
6)执⾏ JavaScript
from lenium import webdriver
browr = webdriver.Chrome()
<('/explore')
这⾥就利⽤ execute_script() ⽅法将进度条下拉到最底部,然后弹出 alert 提⽰框。
3.获取节点信息
通过 page_source 属性可以获取⽹页的源代码,接着就可以使⽤解析库(如正则表达式、Beautiful Soup、pyquery 等)来提取信息。
1)获取属性
我们可以使⽤ get_attribute() ⽅法来获取节点的属性,但是其前提是先选中这个节点。
from lenium import webdriver
from lenium.webdriver import ActionChains
browr = webdriver.Chrome()
url ='/explore'
<(url)
logo = browr.find_element_by_id('zh-top-link-logo')
print(logo)
_attribute('class'))
运⾏之后,程序便会驱动浏览器打开知乎页⾯,然后获取知乎的 logo 节点,最后打印出它的 class。
2)获取⽂本值
每个 WebElement 节点都有 text 属性,直接调⽤这个属性就可以得到节点内部的⽂本信息,这相当于 Beautiful Soup 的 get_text() ⽅法、pyquery 的 text() ⽅法。
from lenium import webdriver
browr = webdriver.Chrome()
url ='/explore'
<(url)
超短裙女教师input= browr.find_element_by_class_name('ExploreSpecialCard-title')
)
运⾏结果
科⽐意外离世,你对他有哪些回忆?汉景帝刘启
3)获取 ID、位置、标签名、⼤⼩
from lenium import webdriver
browr = webdriver.Chrome()
url ='/explore'
<(url)
input= browr.find_element_by_class_name('zu-top-add-question')
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)
这⾥⾸先获得 “提问” 按钮这个节点,然后调⽤其 id、location、tag_name、size 属性来获取对应的属性值。
4.切换 Frame
⽹页中有⼀种节点叫作 iframe,也就是⼦ Frame,相当于页⾯的⼦页⾯,它的结构和外部⽹页的结构完全⼀致。Selenium 打开页⾯后,它默认是在⽗级 Frame ⾥⾯操作,⽽此时如果页⾯中还有⼦ Frame,它是不能获取到⼦ Frame ⾥⾯的节点的。这时就需要使⽤
switch_to.frame() ⽅法来切换 Frame
5.前进后退
import time
from lenium import webdriver
ptions import NoSuchElementException
browr = webdriver.Chrome()
url ='/try/try.php?filename=jqueryui-api-droppable'重阳节什么意思
<(url)
browr.switch_to.frame('iframeResult')
try:
logo = browr.find_element_by_class_name('logo')
except NoSuchElementException:
print('NO LOGO')
browr.switch_to.parent_frame()
logo = browr.find_element_by_class_name('logo')
print(logo)
)
⾸先通过 switch_to.frame() ⽅法切换到⼦ Frame ⾥⾯,然后尝试获取⼦ Frame ⾥的 logo 节点(这是不能找到的),如果找不到的话,就会抛出 NoSuchElementException 异常,异常被捕捉之后,就会输出 NO LOGO。接下来,重新切换回⽗级 Frame,然后再次重新获取节点,发现此时可以成功获取了。
所以,当页⾯中包含⼦ Frame 时,如果想获取⼦ Frame 中的节点,需要先调⽤ switch_to.frame() ⽅法切换到对应的 Frame,然后再进⾏操作。
6.延时等待
在 Selenium 中,get() ⽅法会在⽹页框架加载结束后结束执⾏,此时如果获取 page_source,可能并不是浏览器完全加载完成的页⾯,如果某些页⾯有额外的 Ajax 请求,我们在⽹页源代码中也不⼀定能成功获取到。所以,这⾥需要延时等待⼀定时间,确保节点已经加载出来。
这⾥等待的⽅式有两种:
隐式等待
当使⽤隐式等待执⾏测试的时候,如果 Selenium 没有在 DOM 中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。换句话说,当查找节点⽽节点并没有⽴即出现的时候,隐式等待将等待⼀段时间再查找 DOM,默认的时间是 0。
from lenium import webdriver
browr = webdriver.Chrome()
browr.implicitly_wait(10)
<('/explore')
input= browr.find_element_by_class_name('zu-top-add-question')
print(input)
在这⾥我们⽤ implicitly_wait() ⽅法实现了隐式等待。
显式等待
隐式等待的效果其实并没有那么好,因为我们只规定了⼀个固定时间,⽽页⾯的加载时间会受到⽹络条件的影响。
红领巾手抄报这⾥还有⼀种更合适的显式等待⽅法,它指定要查找的节点,然后指定⼀个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。
from lenium import webdriver
from by import By
from lenium.webdriver.support.ui import WebDriverWait
from lenium.webdriver.support import expected_conditions as EC
browr = webdriver.Chrome()
<('/')
wait = WebDriverWait(browr,10)
input= wait.until(EC.prence_of_element_located((By.ID,'q')))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-arch')))
小说人物名字print(input, button)