安装javascript
pip3 install seleniumcss
测试是否成功html
from selenium import webdriver browser=webdriver.Chrome() #若是能弹出一个空白的chrome浏览器页面,说明配置成功
浏览器对象获取java
from selenium import webdriver #browser=webdriver.Firefox() browser=webdriver.Chrome() #browser=webdriver.Edge() #browser=webdriver.Safari() print(type(browser)) #返回的是一个WebDriver对象 <class 'selenium.webdriver.chrome.webdriver.WebDriver'>
WebDriver对象的方法和属性:python
from selenium import webdriver driver=webdriver.Chrome() driver.get('https://www.baidu.com') driver.execute_script("alert('are you sure');") #它基本能够实现JavaScript的全部功能 PS:可是没有测出来如何获取js执行结果
from selenium import webdriver browser=webdriver.Chrome() browser.get('http://selenium-python.readthedocs.io') browser.execute_script('window.open("https://www.baidu.com");') #在标签页打开URL browser.execute_script('window.open("https://www.taobao.com");') browser.back() #后退到前一个页面 browser.set_page_load_timeout(5) browser.forward() #前进到下一个页面 print(browser.name) print(browser.title) print(browser.current_url) print(browser.current_window_handle) print(browser.get_cookies()) print(type(browser)) # chrome Selenium with Python — Selenium Python Bindings 2 documentation http://selenium-python.readthedocs.io/ CDwindow-243FD31239F20FCC0195DD522A60A0DA [{'domain': '.readthedocs.io', 'expiry': 1530766561, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.2.1126774326.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1593752161, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.2.2096958532.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1530680217, 'httpOnly': False, 'name': '_gat_rtfd', 'path': '/', 'secure': False, 'value': '1'}] <class 'selenium.webdriver.chrome.webdriver.WebDriver'>
页面截图web
from selenium import webdriver driver=webdriver.Chrome() driver.get('http://www.python.org') driver.save_screenshot('screenshot.png') #保持页面截图到当前路径 driver.quit()
将页面滚动到底部:正则表达式
from selenium import webdriver driver=webdriver.Chrome() driver.get('http://www.python.org') #经过DOM中的window对象的scrollTo方法,将窗口位置滚动到指定位置,document.body.scrollHeight返回整个body的高度,因此页面将滚动到页面底部 driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
cookies操做:(PS:这段没有测试)chrome
from selenium import webdriver driver=webdriver.Chrome() driver.get('https://www.baidu.com') print(driver.get_cookies()) #获取全部cookies driver.add_cookie({'name':'name','domain':'www.baidu.com','value':'germey'}) #添加cookie print(driver.get_cookies()) driver.delete_all_cookies() print(driver.get_cookies())
元素定位api
class selenium.webdriver.common.by.By
有各类策略来定位页面中的元素。你可使用最适合你的状况。Selenium提供了如下方法来定位页面中的元素:浏览器
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
要查找多个元素(这些方法将返回一个列表):
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_element和find_elements
(PS:这段也没有测试,之后用到再测试)
from selenium import webdriver from selenium.webdriver.common.by import By driver=webdriver.Chrome() driver.get('http://selenium-python.readthedocs.io/locating-elements.html#locating-elements') data=driver.find_element(By.CLASS_NAME,'simple') #driver.find_element(By.ID,'IDname') #获取ID标签订位元素 #driver.find_element(By.CSS_SELECTOR,'cssname')#CSS选择器定位元素 #driver.find_element(By.LINK_TEXT,'linktext') #连接文本定位元素 #driver.find_element(By.PARTIAL_LINK_TEXT,'linktext') #部分连接文件定位元素 #driver.find_element(By.NAME,'name') #属性名定位元素 #driver.find_element(By.TAG_NAME,'tagname') #标签名定位元素 print(data.text) #打印元素文本内容
元素对象
from selenium import webdriver from selenium.webdriver.chrome.options import Options opt=Options() opt.add_argument('headless') driver=webdriver.Chrome(chrome_options=opt) driver.get('http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement') element=driver.find_element_by_id('module-selenium.webdriver.remote.webelement') print(element) print(type(element)) #返回一个webelement对象 <selenium.webdriver.remote.webelement.WebElement (session="dfaee65201abdf5a931306df6e7fe421", element="0.95256057244967-1")> <class 'selenium.webdriver.remote.webelement.WebElement'>
selenium.webdriver.remote.webelement.WebElement为一个DOM元素,它的方法和属性包括:
元素存在判断
# 该方法用来确认元素是否存在,若是存在返回flag=true,不然返回false def isElementExist(driver, element): flag = True try: driver.find_element_by_css_selector(element) return flag except: flag = False return flag # 调用 driver是浏览器对象 if isElementExist(driver, "[class='airy-ad-prompt-container']"): print("有") else: print("没有")
抓取网页源码,有了它剩下的就是正则表达式捕获了
from selenium import webdriver driver=webdriver.Chrome() driver.get('http://www.cnblogs.com/zhangxinqi/') element=driver.find_element_by_id('q') #获取输入框元素 element.send_keys('python3之requests') #发送元素 button=driver.find_element_by_id('btnZzk') #获取搜索按钮 button.click() #发送搜索动做 data=driver.page_source #这里返回html源码 print(driver.current_url) #打印URL print(data) print(type(element)) driver.close()
动做模拟
class selenium.webdriver.common.action_chains.ActionChains(driver)
在上面的实例中咱们针对的是某个节点元素的操做,若是要对没有特定元素的对象操做如鼠标拖拽、键盘按键等,这些动做就称为动做链,selenium使用ActionChains()类来实现鼠标移动,鼠标按钮操做,按键操做和上下文菜单交互,悬停和拖放等
拖拽到指定目标(PS:没有测试)
element = driver.find_element_by_name("source") target = driver.find_element_by_name("target") from selenium.webdriver import ActionChains action_chains = ActionChains(driver) action_chains.drag_and_drop(element, target).perform()
鼠标操做(PS:没有测试)
menu = driver.find_element_by_css_selector(".nav") #获取element对象 hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1") #获取点击对象 #建立鼠标对象 actions = ActionChains(driver) #移动鼠标到对象 actions.move_to_element(menu) #点击对象 actions.click(hidden_submenu) #执行操做 actions.perform()
弹出对话框
class selenium.webdriver.common.alert.Alert(driver)
Alert内置支持处理弹窗对话框,方法:
(PS:没有测试)
import time from selenium import webdriver from selenium.webdriver.common.alert import Alert driver=webdriver.Chrome() driver.get('https://www.baidu.com') driver.execute_script("alert('肯定');") #弹出窗口 time.sleep(2) print(driver.switch_to.alert.text) #获取alert文本 alert=Alert(driver).accept() #自动点击肯定窗口
键盘操做
class selenium.webdriver.common.keys.Keys
selenium提供一个keys包来模拟全部的按键操做,下面咱们介绍下一些经常使用的按键操做:
实现点击页面从python的pypi页面下载selenium源码包:(PS:没有测试)
import requests from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains driver=webdriver.Chrome() driver.get('https://pypi.org/') element=driver.find_element_by_id('search') #获取输入框 element.send_keys('selenium') #搜索selenium包 element.send_keys(Keys.ENTER) #按回车键 element_a=driver.find_element_by_link_text('selenium') #定位selenium包连接 ActionChains(driver).move_to_element(element_a).click(element_a).perform() #按左键点击连接执行 element_down=driver.find_element_by_link_text('Download files') #定位下载连接 ActionChains(driver).move_to_element(element_down).click(element_down).perform() #按左键点击连接 element_selenium=driver.find_element_by_link_text('selenium-3.13.0.tar.gz') #定位元素selenium下载包连接 data=element_selenium.get_attribute('href') #获取连接地址 with open('selenium-3.13.0.tar.gz','wb') as f: source=requests.get(data).content #请求下载连接地址获取二进制包数据 f.write(source) #写入数据 f.close() driver.quit()
延时等待
目前,大多数Web应用程序都在使用AJAX技术。当浏览器加载页面时,该页面中的元素可能以不一样的时间间隔加载。这使定位元素变得困难:若是DOM中还没有存在元素,则locate函数将引起ElementNotVisibleException异常。使用等待,咱们能够解决这个问题。等待在执行的操做之间提供了一些松弛 - 主要是使用元素定位元素或任何其余操做。
Selenium Webdriver提供两种类型的等待 - 隐式和显式。显式等待使WebDriver等待某个条件发生,而后再继续执行。在尝试查找元素时,隐式等待会使WebDriver轮询DOM一段时间。
显示等待:
显示等待是根据定义的代码,用于在进一步执行代码以前等待某个条件发送,它提供了一些便捷方法,能够编写在仅须要等待的代码上,实现方法须要WebDriverWait与ExpectedCondition结合使用:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox() driver.get("http://somedomain/url_that_delays_loading") try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) finally: driver.quit()
在抛出TimeoutException异常以前将等待10秒或者在10秒内发现了查找的元素。 WebDriverWait 默认状况下会每500毫秒调用一次ExpectedCondition直到结果成功返回。 ExpectedCondition成功的返回结果是一个布尔类型的true或是不为null的返回值。中文文档 https://selenium-python-zh.readthedocs.io/en/latest/getting-started.html#id2
其余等待条件:
中文文档 https://selenium-python-zh.readthedocs.io/en/latest/waits.html
摘自 https://www.cnblogs.com/zhangxinqi/p/9259808.html
最后附上一份截图源码,改了好一会才完成,原始版,未整理
#!/usr/bin/python3 # 截图测试 # from selenium import webdriver import unittest import os, sys, time import exescript from PIL import Image # 合并截图,而且裁剪多余部分 def image_merge(li_path, img_width, img_height): print("图片处理") max_width = 0 total_height = 0 # 计算合成后图片的宽度(以最宽的为准)和高度 for img_path in li_path: if os.path.exists(img_path): img = Image.open(img_path) width, height = img.size if width > max_width: max_width = width total_height += height # 产生一张空白图 new_img = Image.new("RGB", (max_width, total_height), 255) # 合并 x = y = 0 for img_path in li_path: if os.path.exists(img_path): img = Image.open(img_path) width, height = img.size new_img.paste(img, (x, y)) y += height # 裁剪多余 print(new_img.size) new_img.save("data/xq.jpg", "JPEG", quality=95) img1 = Image.open("data/xq.jpg") print("宽度", img1.width) print("图片宽度", img_width) # 计算白边 cut = ((img1.width - img_width) / 2) - 100 print("白边", cut) ok_scr = img1.width - cut img_cut_size = (cut, 0, ok_scr, img_height) img2 = img1.crop(img_cut_size) img2.save("data/xq_cut.jpg", "JPEG", quality=95) # 登陆 current_time = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time())) current_time1 = time.strftime("%Y-%m-%d", time.localtime(time.time())) print(current_time) print(current_time1) dpath = "config\chromedriver.exe" options = webdriver.ChromeOptions() options.add_argument( 'user-agent="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"' ) options.add_argument("--headless") # options.add_argument("headless") # 静默浏览器 # 设置成中文 # options.add_argument('lang=zh_CN.UTF-8') options.add_argument("en-us") # 谷歌文档提到须要加上这个属性来规避bug options.add_argument("--disable-gpu") # 禁止加载全部插件,能够增长速度。能够经过about:plugins页面查看效果 options.add_argument("–disable-plugins") # 配了环境变量第一个参数就能够省了,否则传绝对路径 driver = webdriver.Chrome(executable_path=dpath, chrome_options=options) # driver = webdriver.Chrome(executable_path=dpath) url = "https://www.amazon.com/dp/B01L1F1OV6" # 设定屏幕宽 和 高 w_width = 1920 w_height = 1080 driver.set_window_size(w_width, w_height) driver.get(url) # 必须打印图片路径HTMLTestRunner才能捕获而且生成路径,\image\**\\**.png 是获取路径的条件,必须这样的目录 # 设置存储图片路径,测试结果图片能够按照天天进行区分 # 经过if进行断言判断 # driver.get("https://baidu.com/") # # 新建立路径“.”表示当前整个.py文件的路径所在的位置,“\\”路径分割符,其中的一个是“\”表示转义字符 # pic_path = ".\\result\\image\\" + current_time1 + "\\" + current_time + ".png" # print(pic_path) # time.sleep(5) # print(driver.title) # 截取当前url页面的图片,并将截取的图片保存在指定的路径下面(pic_path),注:如下两种方法均可以 # driver.save_screenshot(pic_path) # 能够注入,可是不必定能够返回 time.sleep(5) # exejs = exescript.ExeJs(driver) # js_th ='return document.getElementsByClassName("a-section a-spacing-extra-large bucket")[0].clientHeight.toString()' # exejs.exeWrap(js_th) th = driver.execute_script("return document.title;") print(th) # 滚动到指定位置 print("滚动到指定位置") js = 'window.location.hash="aplus"' driver.execute_script(js) # 不容许这样使用符号类名 # ts1 = driver.find_element_by_class_name("a-section.a-spacing-extra-large.bucket") li_img = [] # 定义截图保存路径 try: dw = driver.find_element_by_id("dpx-aplus-3p-product-description_feature_div") # print("定位1", dw.size) # print("定位1", dw.location) # 可行 dw1_height = dw.location["y"] # print("定位1", dw.location_once_scrolled_into_view) xq = driver.find_element_by_css_selector( "[class='a-section a-spacing-extra-large bucket']" ) # print("定位2", xq.size) xq_width = xq.size["width"] xq_height = xq.size["height"] all_height = 0 all_height = xq_height driver.save_screenshot("data/sc_1.png") li_img.append("data/sc_1.png") # 获取浏览器可视区域高度 th_see_height = driver.execute_script("return window.innerHeight;") print("可视高度", th_see_height) # 详情自己尺寸 xq_ok = driver.find_element_by_css_selector("[class='aplus-v2 desktop celwidget']") # print("定位2", xq.size) xq_ok_width = xq_ok.size["width"] print("展现高度", xq_ok_width) # 若是详情高度大于设定屏幕高度,就须要二次滚动,甚至屡次滚动 num = 2 while all_height >= th_see_height: print("滚动到指定位置") th = 0 th = dw1_height + th_see_height js = "window.scroll(0," + str(th) + ")" driver.execute_script(js) t_path = "" t_path = "data/sc_" + str(num) + ".png" driver.save_screenshot(t_path) li_img.append(t_path) all_height = all_height - th_see_height if all_height <= th_see_height: break else: num += 1 print("截图次数", num) print("截图完成,数据以下") print("路径", li_img) print("尺寸宽", xq_width) print("尺寸高", xq_height) image_merge(li_img, xq_ok_width, xq_height) except Exception as result: print("检测出异常{}".format(result)) time.sleep(1) driver.close()