# DrissionPage学习
官网:http://drissionpage.cn/features/intimate/
自动化测试框架:DrissionPage
1.DrissionPage事件 1.1元素定位查找 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 # 根据属性查找,@ 后面可跟任意属性 page.ele('@id:ele_id' , timeout=2 ) # 查找 id 为 ele_id 的元素,设置等待时间2 秒 page.eles('@class' ) # 查找所有拥有 class 属性的元素 page.eles('@class:class_name' ) # 查找所有 class 含有 ele_class 的元素 page.eles('@class=class_name' ) # 查找所有 class 等于 ele_class 的元素 # 根据 class 或 id 查找 page.ele('#ele_id' ) # 等价于 page.ele('@id=ele_id' ) page.ele('#:ele_id' ) # 等价于 page.ele('@id:ele_id' ) page.ele('.ele_class' ) # 等价于 page.ele('@class=ele_class' ) page.ele('.:ele_class' ) # 等价于 page.ele('@class:ele_class' ) # 根据 tag name 查找 page.ele('tag:li' ) # 查找第一个 li 元素 page.eles('tag:li' ) # 查找所有 li 元素 # 根据 tag name 及属性查找 page.ele('tag:div@class=div_class' ) # 查找 class 为 div_class 的 div 元素 page.ele('tag:div@class:ele_class' ) # 查找 class 含有 ele_class 的 div 元素 page.ele('tag:div@class=ele_class' ) # 查找 class 等于 ele_class 的 div 元素 page.ele('tag:div@text():search_text' ) # 查找文本含有 search_text 的 div 元素 page.ele('tag:div@text()=search_text' ) # 查找文本等于 search_text 的 div 元素 # 根据文本内容查找 page.ele('search text' ) # 查找包含传入文本的元素 page.eles('text:search text' ) # 如文本以 @、tag:、css:、xpath:、text: 开头,则应在前加上 text: 避免冲突 page.eles('text=search text' ) # 文本等于 search_text 的元素 # 根据 xpath 或 css selector 查找 page.eles('xpath://div[@class="ele_class"]' ) page.eles('css:div.ele_class' ) # 根据 loc 查找 loc1 = By.ID, 'ele_id' loc2 = By.XPATH, '//div[@class="ele_class"]' page.ele(loc1) page.ele(loc2) # 查找下级元素 element = page.ele('@id:ele_id' ) element.ele('@class:class_name' ) # 在 element 下级查找第一个 class 为 ele_class 的元素 element.eles('tag:li' ) # 在 ele_id 下级查找所有li元素 # 根据位置查找 element.parent # 父元素 element.next # 下一个兄弟元素 element.prev # 上一个兄弟元素 # 获取 shadow-root,把它作为元素对待。只支持 open 的 shadow-root ele1 = element.shadow_root.ele('tag:div' ) # 串连查找 page.ele('@id:ele_id' ).ele('tag:div' ).next.ele('some text' ).eles('tag:a' ) # 简化写法 eles = page('@id:ele_id' )('tag:div' ).next('some text' ).eles('tag:a' ) ele2 = ele1('tag:li' ).next('some text' )
1.2元素操作 1 2 3 4 5 6 7 8 9 10 11 12 element .click(by_js) element .input(value ) element .run_script(js) element .submit() element .clear () element .screenshot(path, filename) element .select(text ) element .set_attr(attr, value ) element .remove_attr(attr) element .drag(x, y, speed, shake) element .drag_to(ele_or_loc, speed, shake) element .hover()
1.3获取元素属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 element .html element .inner_html element .tag element .text element .comments element .link element .texts() element .attrs element .attr(attr) element .css_path element .xpath element .parent element .next element .prev element .parents(num ) element .nexts(num , mode) element .prevs(num , mode) element .ele(loc_or_str, timeout) element .eles(loc_or_str, timeout)
2.DrissionPage基本使用 2.1控制浏览器,导入ChromiumPage
:
from DrissionPage import ChromiumPage
2.1.1 示例代码1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from DrissionPage import ChromiumPage page = ChromiumPage()page .get('https://gitee.com/login' ) ele = page .ele('#user_login' ) ele.input('账号' )page .ele('#user_password' ).input('密码' )page .ele('@value=登 录' ).click()
2.1.2示例代码2(Recorder是追加写入): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 from DrissionPage import ChromiumPagefrom DataRecorder import Recorder from time import sleep page = ChromiumPage() recorder = Recorder('data.csv' ) recorder.add_data(("标题" , "导演" , "上映时间" , "评分" )) page.get ('https://www.maoyan.com/board/4' ) while True: for mov in page.eles('t:dd' ): score = mov('.score' ).text title = mov('@data-act=boarditem-click' ).attr('title' ) star = mov('.star' ).text time = mov('.releasetime' ).text recorder.add_data((title, star, time , score)) sleep(1 ) btn = page('下一页' , timeout=2 ) if btn: btn.click() page.wait .load_start() else : break recorder.record()
2.1.3 示例代码3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from DrissionPage import ChromiumPageimport timepage = ChromiumPage()page .get('https://www.zkh.com/?utm_source=baidu&utm_medium=CPT')time .sleep(1 )page .ele('xpath://*[@id="app" ]/div/div/div[3 ]/div/div[1 ]/div[1 ]/input').input("口罩" )time .sleep(1 )page .ele('xpath://*[@id="app" ]/div/div/div[3 ]/div/div[1 ]/button').click()while True: page .wait.load_start() page .scroll.to_location(0 ,10000 ) #滚动到指定位置 time .sleep(0 .5 ) page .scroll.to_location(0 , 10000 ) time .sleep(0 .5 ) page .scroll.to_location(0 , 10000 ) time .sleep(0 .5 ) divs =page.eles('xpath://div[@class="goods-name clamp2" ]') for i in divs: title = i.attr('title') print (title)
2.2收发数据包,导入SessionPage
:
from DrissionPage import SessionPage
2.2.1示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 from DrissionPage import SessionPage page = SessionPage() for i in range (1 , 6 ): page.get(f'https://gitee.com/explore/all?page={i} ' ) links = page.eles('.title project-namespace-path' ) for link in links: print (f"{link.text} :{link.link} " )
2.2.2下载网页 1 2 3 4 5 6 7 from DrissionPage import SessionPage url = 'https://www.baidu.com/img/flexible/logo/pc/result.png' save_path = r'images' page = SessionPage() page.download(url, save_path, 'img' )
3.获取新窗口句柄 3.1.无需切入切出,逻辑清晰 使用过 selenium 的人都知道,selenium 同一时间只能操作一个标签页或<iframe>
元素,要操作其它标签页,或<iframe>
元素,需要用switch_to()
方法切换,操作后还要切换回来。如果是多级<iframe>
,还要逐级切入,相当麻烦。
DrissionPage 则无需这些麻烦的操作,它把每个标签页和<iframe>
都看作独立的对象,可以同时并发操作,而且可以直接跨多层<iframe>
获取里面的元素,然后直接处理,非常方便。
对比一下,获取 2 层<iframe>
内一个 id 为'div1'
的元素:
1 2 3 4 5 6 7 8 driver.switch_to.frame(0) driver.switch_to.frame(0) ele = driver.find_element(By.ID, 'div1' ) driver.switch_to.default_content() ele = page('#div1' )
多标签页同时操作,selenium 无此功能:
1 2 3 4 5 tab1 = page.get_tab(1)tab2 = page.get_tab(2)tab1 .get ('https:tab2 .get ('https:
3.2 示例代码1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 from DrissionPage import ChromiumPage import timepage = ChromiumPage()这句意思是打开一个浏览器,这个浏览器是安装DrissionPage时自动安装的page .get('https://www.baidu.com' ) time.sleep (1 )page .ele('xpath://*[@id="kw"]' ).input("宿舍" ) time.sleep (1 )page .ele('xpath://*[@id="su"]' ).click() time.sleep (1 )page .ele('xpath://*[@id="3"]/div/div[1]/h3/a' ).click() ab=page .get_tab(page .latest_tab) page .wait.load_start()print (ab.title) time.sleep (1 ) ab.ele('xpath:/html/body/div[1]/div[3]/form/div/input[4]' ).input("家" ) ab.ele('xpath:/html/body/div[1]/div[3]/form/div/span' ).click() lis = ab.ele('xpath:/html/body/div[2]/div[1]/div/div[2]/ul' ) lis1 = lis.eles('tag:li' ) for i in lis1: lis2 = i.eles('tag:a' ) for j in lis2: href=j.attr('href' ) title=j.attr('title' ) print (href,title) time.sleep (4 )page .close_tabs(ab) ac=page .get_tab(page .latest_tab) print (ac.title) time.sleep (1 ) ac.ele('xpath://*[@id="6"]/div/div[1]/h3/a' ).click() time.sleep (2 )page .quit ()
4.与selenium对比 与selenium对比
4.1跳转到一个标签页 1 2 3 4 5 driver .switch_to.window(driver.window_handles[0 ])tab = page.get_tab(1 )
4.2按文本选择下拉列表 1 2 3 4 5 6 7 # 使用 selenium: from selenium.webdriver.support.select import Select select_element = Select (element) select_element.select_by_visible_text('text' )# 使用 DrissionPage: element.select ('text' )
4.3拖拽一个元素 1 2 3 4 5 # 使用 selenium: ActionChains(driver).drag_and_drop(ele1, ele2).perform () # 使用 DrissionPage: ele1.drag_to(ele2)
4.4滚动窗口到底部(保持水平滚动条不变) 1 2 3 4 5 driver.execute_script("window.scrollTo(document.documentElement.scrollLeft, document.body.scrollHeight);" )page .scroll.to_bottom()
4.5设置 headless 模式 1 2 3 4 5 6 options = webdriver.ChromeOptions()options .add_argument("--headless" )set_headless (True)
4.6获取伪元素内容 1 2 3 4 5 text = webdriver.execute_script('return window.getComputedStyle(arguments[0 ], "::after" ).getPropertyValue("content" );', element)text = element.pseudo.after
4.7用 xpath 直接获取属性或文本节点(返回文本) 1 2 3 4 5 6 相当复杂 class_name = element('xpath://div[@id ="div_id" ]/@class ') text = element('xpath://div[@id ="div_id" ]/text()[2 ]')
5.模式切换 http://drissionpage.cn/features/features_demos/change_mode/
用浏览器登录网站,然后切换到 requests 读取网页。两者会共享登录信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from DrissionPage import WebPage from time import sleep page = WebPage() page .get('https://gitee.com/profile' ) page .ele('@id:user_login' ).input('your_user_name' ) page .ele('@id:user_password' ).input('your_password\n' )page .wait.load_start()page .change_mode() print ('登录后title:' , page .title, '\n' ) 登录后title: 个人资料 - 码云 Gitee.com
获取登录后的元素 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 foot = page.ele('#footer-left' ) first_col = foot.ele('css:>div' ) lnk = first_col.ele('text:命令学' ) text = lnk.text href = lnk.attr('href' ) print(text , href, '\n' )text = page('@id:footer-left' )('css:>div' )('text:命令学' ).text print(text ) Git 命令学习 https ://oschina.gitee.io/learn-git-branching/ Git 命令学习