python-selenium库详解
python-selenium库详解
Selenium 是⼀个⾃动化测试⼯具,利⽤它可以驱动浏览器执⾏特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页⾯的源代码,做到可见即可爬。对于⼀些 JavaScript 动态渲染的页⾯来说,此种抓取⽅式⾮常有效。
1.selenium库的安装
pip3 install selenium
2.selenium库的基本⽤法
1)声明浏览器对象
Selenium ⽀持⾮常多的浏览器,如 Chrome、Firefox、Edge 等,还有 Android、BlackBerry 等⼿机端的浏览器。另外,也⽀持⽆界⾯浏览器 PhantomJS,我们可以⽤如下⽅式初始化:
from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.PhantomJS()
browser = webdriver.Safari()
这样就完成了浏览器对象的初始化并将其赋值为 browser 对象。
2)访问页⾯
可以⽤ get() ⽅法来请求⽹页,参数传⼊链接 URL 即可
from selenium import webdriver
browser = webdriver.Chrome()
<('www.taobao')
print(browser.page_source)
browser.close()
运⾏后发现,弹出了 Chrome 浏览器并且⾃动访问了淘宝,然后控制台输出了淘宝页⾯的源代码,随后浏览器关闭。
3)查结点
想要从淘宝页⾯中提取搜索框这个节点,可以发现,它的 id 是 q,name 也是 q
from selenium import webdriver
browser = webdriver.Chrome()
<('www.taobao')
input_first = browser.find_element_by_id('q')
input_second = browser.find_element_by_css_selector('#q')
input_third = browser.find_element_by_xpath('//*[@id="q"]')
print(input_first, input_second, input_third)
browser.close()
运⾏结果
所有获取单个节点的⽅法:
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_selector
另外,Selenium 还提供了通⽤⽅法 find_element(),它需要传⼊两个参数:查⽅式 By 和值。实际上,它就是 find_element_by_id()这种⽅法的通⽤函数版本,⽐如 find_element_by_id(id) 就等价于 find_element(By.ID, id),⼆者得到的结果完全⼀致。
from selenium import webdriver
from selenium.webdrivermon.by import By
browser = webdriver.Chrome()
<('www.taobao')
input_first = browser.find_element(By.ID,'q')
print(input_first)
browser.close()
多个节点
如果查的⽬标在⽹页中只有⼀个,那么完全可以⽤ find_element() ⽅法。如果要查所有满⾜条件的节点,需要⽤ find_elements() 这样的⽅法。注意,在这个⽅法的名称中,element 多了⼀个 s。
要查淘宝左侧导航条的所有条⽬
from selenium import webdriver
browser = webdriver.Chrome()
<('www.taobao')
lis = browser.find_elements_by_css_selector('.service-bd li')
print(lis)
browser.close()
所有获取多个节点的⽅法:
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_selector
我们也可以直接⽤ find_elements() ⽅法来选择
lis = browser.find_elements(By.CSS_SELECTOR,'.service-bd li')
4)节点交互
Selenium 可以驱动浏览器来执⾏⼀些操作,也就是说可以让浏览器模拟执⾏⼀些动作。⽐较常见的⽤法有:输⼊⽂字时⽤ send_keys ⽅法,清空⽂字时⽤ clear ⽅法,点击按钮时⽤ click ⽅法。
from selenium import webdriver
import time
browser = webdriver.Chrome()
<('www.taobao')
input=browser.find_element_by_id('q')
input.send_keys('iphone')
time.sleep(1)
input.clear()
input.send_keys('ipad')
button=browser.find_element_by_class_name('btn-search')
button.click()
这⾥⾸先驱动浏览器打开淘宝,然后⽤ find_element_by_id() ⽅法获取输⼊框,然后⽤ send_keys()
⽅法输⼊ iPhone ⽂字,等待⼀秒后⽤ clear() ⽅法清空输⼊框,再次调⽤ send_keys() ⽅法输⼊ iPad ⽂字,之后再⽤ find_element_by_class_name() ⽅法获取搜索按钮,最后调⽤ click() ⽅法完成搜索动作。
5)动作链
⼀些交互动作都是针对某个节点执⾏的。⽐如,对于输⼊框,我们就调⽤它的输⼊⽂字和清空⽂字⽅法;对于按钮,就调⽤它的点击⽅法。还有另外⼀些操作,它们没有特定的执⾏对象,⽐如⿏标拖曳、键盘按键等,这些动作⽤另⼀种⽅式来执⾏,那就是动作链。
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url ='www.runoob/try/try.php?filename=jqueryui-api-droppable'
<(url)
browser.switch_to.frame('iframeResult')
source = browser.find_element_by_css_selector('#draggable')
target = browser.find_element_by_css_selector('#droppable')
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()
打开⽹页中的⼀个拖曳实例,然后依次选中要拖曳的节点和拖曳到的⽬标节点,接着声明 ActionChains 对象并将其赋值为 actions 变量,然后通过调⽤ actions 变量的 drag_and_drop() ⽅法,再调⽤ perform() ⽅法执⾏动作,此时就完成了拖曳操作
6)执⾏ JavaScript
from selenium import webdriver
browser = webdriver.Chrome()
<('www.zhihu/explore')
家庭安全隐患这⾥就利⽤ execute_script() ⽅法将进度条下拉到最底部,然后弹出 alert 提⽰框。
3.获取节点信息
通过 page_source 属性可以获取⽹页的源代码,接着就可以使⽤解析库(如正则表达式、Beautiful Soup、pyquery 等)来提取信息。
1)获取属性
我们可以使⽤ get_attribute() ⽅法来获取节点的属性,但是其前提是先选中这个节点。
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url ='www.zhihu/explore'
<(url)
logo = browser.find_element_by_id('zh-top-link-logo')
print(logo)
_attribute('class'))
运⾏之后,程序便会驱动浏览器打开知乎页⾯,然后获取知乎的 logo 节点,最后打印出它的 class。
2)获取⽂本值
每个 WebElement 节点都有 text 属性,直接调⽤这个属性就可以得到节点内部的⽂本信息,这相当于 Beautiful Soup 的 get_text() ⽅法、pyquery 的 text() ⽅法。
from selenium import webdriver
browser = webdriver.Chrome()
生僻字歌词带拼音url ='www.zhihu/explore'
<(url)
汉字的手抄报input= browser.find_element_by_class_name('ExploreSpecialCard-title')
)
运⾏结果
科⽐意外离世,你对他有哪些回忆?
3)获取 ID、位置、标签名、⼤⼩
from selenium import webdriver
browser = webdriver.Chrome()
url ='www.zhihu/explore'
<(url)
input= browser.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 selenium import webdriver
工作责任心ptions import NoSuchElementException
browser = webdriver.Chrome()
url ='www.runoob/try/try.php?filename=jqueryui-api-droppable'
<(url)
browser.switch_to.frame('iframeResult')
try:
logo = browser.find_element_by_class_name('logo')
except NoSuchElementException:
print('NO LOGO')
browser.switch_to.parent_frame()
logo = browser.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 selenium import webdriver
browser = webdriver.Chrome()
browser.implicitly_wait(10)
<('www.zhihu/explore')
input= browser.find_element_by_class_name('zu-top-add-question')
print(input)
在这⾥我们⽤ implicitly_wait() ⽅法实现了隐式等待。
显式等待
隐式等待的效果其实并没有那么好,因为我们只规定了⼀个固定时间,⽽页⾯的加载时间会受到⽹络条件的影响。
这⾥还有⼀种更合适的显式等待⽅法,它指定要查的节点,然后指定⼀个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。
from selenium import webdriver
from selenium.webdrivermon.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
<('www.taobao/')
wait = WebDriverWait(browser,10)
input= wait.until(EC.presence_of_element_located((By.ID,'q')))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search')))
print(input, button)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论