Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接调用浏览器,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等。
工作原理:代码——调用webdriver——操作浏览器
利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)
(1)安装selenium:pip/pip3 install selenium
(2)下载版本符合的webdriver
①查看谷歌浏览器的版本
②点击进入不同版本的chromedriver下载页面
③点击notes.txt进入版本说明页面
④查看chrome和chromedriver匹配的版本
⑤根据操作系统下载正确版本的chromedriver
⑥解压压缩包后获取python代码可以调用的谷歌浏览器的webdriver可执行文件
windows为chromedriver.exe、linux和macos为chromedriver
⑦chromedriver环境的配置
1)windows环境下需要将 chromedriver.exe 所在的目录设置为path环境变量中的路径
2)nux/mac环境下,将 chromedriver 所在的目录设置到系统的PATH环境值中,参考
(4)selenium的简单使用
①创建浏览器对象(打开浏览器):driver = webdriver.XXX()
②发送请求:driver.get(url)
③操作浏览器:JavaScript
④退出浏览器:driver.quit()
import time
from selenium import webdriver
# 通过指定chromedriver的路径来实例化driver对象,chromedriver放在当前目录。
# driver = webdriver.Chrome(executable_path='./chromedriver')
# chromedriver已经添加环境变量
driver = webdriver.Chrome()
# 控制浏览器访问url地址
driver.get("https://www.baidu.com/")
# 在百度搜索框中搜索'python'
driver.find_element_by_id('kw').send_keys('python')
# 点击'百度搜索'
driver.find_element_by_id('su').click()
time.sleep(6)
# 退出浏览器
driver.quit()
(1)driver对象的常用属性和方法
driver.page_source
当前标签页浏览器渲染之后的网页源代码driver.current_url
当前标签页的urldriver.close()
关闭当前标签页,如果只有一个标签页则关闭整个浏览器driver.quit()
关闭浏览器driver.forward()
页面前进driver.back()
页面后退driver.screen_shot(img_name)
页面截图(常用验证码截图)(2)driver对象定位标签元素获取标签对象的方法
find_element(s)_by_xpath (返回一个包含元素的列表)
find_element(s)_by_css_selector (根据css选择器来获取元素列表)
find_element_by_id (返回一个元素)
find_element(s)_by_class_name (根据类名获取元素列表)
find_element(s)_by_name (根据标签的name属性值返回包含标签对象元素的列表)
find_element(s)_by_link_text (根据连接文本获取元素列表)
find_element(s)_by_partial_link_text (根据链接包含的文本获取元素列表)
find_element(s)_by_tag_name (根据标签名获取元素列表)
注意:
- find_element和find_elements的区别:
- 多了个s就返回列表,没有s就返回匹配到的第一个标签对象
- find_element匹配不到就抛出异常,find_elements匹配不到就返回空列表
- by_link_text和by_partial_link_tex的区别:全部文本和包含某个文本
(3)标签对象提取文本内容和属性值
element.click()
:对定位到的标签对象进行点击操作element.send_keys(data)
:对定位到的标签对象输入数据element.text
:通过定位获取的标签对象的text
属性,获取文本内容element.get_attribute("属性名")
:通过定位获取的标签对象的get_attribute
函数,传入属性名,来获取属性的值#coding:utf-8
from selenium import webdriver
# 1.创建浏览器对象
driver = webdriver.Chrome()
# 2.操作浏览器对象
driver.get('http://www.baidu.com')
# 2.定位元素
# driver.find_element_by_xpath('//*[@id="kw"]').send_keys('python37')
# driver.find_element_by_id('kw').send_keys('python37')
# driver.find_element_by_name('wd').send_keys('python37')
# 通过class属性值进行元素定位
# driver.find_element_by_class_name('s_ipt').send_keys('python37')
# driver.find_element_by_css_selector('#kw').send_keys('python37')
# driver.find_element_by_xpath('//*[@id="su"]').click()
# print(driver.find_element_by_tag_name('title'))
# 通过含有链接的完整文本内容进行元素定位 链接文本(链接和文本在同一个标签中)
# driver.find_element_by_link_text('hao12').click()
driver.find_element_by_partial_link_text('hao').click()
(1)selenium标签页的切换
# 1. 获取当前所有的标签页的句柄构成的列表
current_windows = driver.window_handles
# 2. 根据标签页句柄列表索引下标进行切换
driver.switch_to.window(current_windows[0])
案例1:
#coding:utf-8
from selenium import webdriver
import time
# 1.创建浏览器对象
driver = webdriver.Chrome()
# 2.操作浏览器对象
driver.get('https://gz.58.com')
driver.find_elements_by_xpath('/html/body/div[3]/div[1]/div[1]/div/div[1]/div[1]/span[1]/a')[0].click()
# 3.获取当前标签页句柄
current_windows = driver.window_handles
# 4.根据标签页句柄列表索引下标进行切换
driver.switch_to.window(current_windows[-1])
# 5.操作新标签页
driver.find_elements_by_xpath('/html/body/div[7]/div[2]/ul/li[1]/div[2]/h2/a')[0].click()
time.sleep(3)
driver.quit()
(2)switch_to切换frame标签
iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是driver.switch_to.frame(frame_element)
。
切换到定位的frame标签嵌套的页面中
driver.switch_to.frame(通过find_element_by函数定位的frame、iframe标签对象)
利用切换标签页的方式切出frame标签
windows = driver.window_handles
driver.switch_to.window(windows[0])
案例:登录QQ空间
from selenium import webdriver
import time
# 1.创建浏览器对象
driver = webdriver.Chrome()
# 2.操作浏览器对象
driver.get('https://qzone.qq.com/')
# 3.切换到定位的frame标签嵌套的页面中
login_frame = driver.find_element_by_xpath('//*[@id="login_frame"]')
driver.switch_to.frame(login_frame)
# 4.操作frame标签嵌套的页面的内容
driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="u"]').send_keys("账号")
time.sleep(2)
driver.find_element_by_xpath('//*[@id="p"]').send_keys("密码")
time.sleep(2)
driver.find_element_by_xpath('//*[@id="login_button"]').click()
(3)selenium对cookie的处理
# 获取当前标签页的全部cookie信息
print(driver.get_cookies())
# 把cookie转化为字典
cookies_dict = {
cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}
#删除一条cookie
driver.delete_cookie("CookieName")
# 删除所有的cookie
driver.delete_all_cookies()
driver.get_cookies()返回列表,其中包含的是完整的cookie信息!不光有name、value,还有domain等cookie其他维度的信息。所以如果想要把获取的cookie信息和requests模块配合使用的话,需要转换为name、value作为键值对的cookie字典
(5) selenium控制浏览器执行js代码:driver.execute_script(js)
(6)页面等待
1)强制等待time.sleep()
2)隐式等待driver.implicitly_wait(10) # 隐式等待,最长等20秒
3)显式等待(用于软件测试较多)
WebDriverWait(driver, 20, 0.5)
(7)selenium开启无界面模式
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--disable-gpu")
driver = webdriver.Chrome(chrome_options=options)
注意:macos中chrome浏览器59+版本,Linux中57+版本才能使用无界面模式!
from selenium import webdriver
options = webdriver.ChromeOptions() # 创建一个配置对象
options.add_argument("--headless") # 开启无界面模式
options.add_argument("--disable-gpu") # 禁用gpu
# options.set_headles() # 无界面模式的另外一种开启方式
driver = webdriver.Chrome(chrome_options=options) # 实例化带有配置的driver对象
driver.get('http://www.baidu.com')
print(driver.title)
driver.quit()
(7)selenium使用代理ip
options = webdriver.ChromeOptions()
options.add_argument('--proxy-server=http://202.20.16.82:9527')
driver = webdriver.Chrome('./chromedriver', chrome_options=options)
from selenium import webdriver
options = webdriver.ChromeOptions() # 创建一个配置对象
options.add_argument('--proxy-server = http://202.20.16.82:9527') # 使用代理ip
driver = webdriver.Chrome(chrome_options=options) # 实例化带有配置的driver对象
driver.get('http://www.itcast.cn')
print(driver.title)
driver.quit()
(8) selenium替换user-agent
options = webdriver.ChromeOptions()
options.add_argument('--user-agent=Mozilla/5.0 HAHA')
driver = webdriver.Chrome('./chromedriver', chrome_options=options)
from selenium import webdriver
options = webdriver.ChromeOptions() # 创建一个配置对象
options.add_argument('--user-agent=Mozilla/5.0 HAHA') # 替换User-Agent
driver = webdriver.Chrome('./chromedriver', chrome_options=options)
driver.get('http://www.itcast.cn')
print(driver.title)
driver.quit()
from selenium import webdriver
import time
class Douyu(object):
def __init__(self):
self.url = "https://www.douyu.com/directory/all"
self.driver = webdriver.Chrome()
def parse_data(self):
# 页面等待
time.sleep(3)
# 定位元素
room_list = self.driver.find_elements_by_xpath('//*[@id="listAll"]/section[2]/div[2]/ul/li/div')
print(len(room_list))
# 遍历房间列表,获取每一个房间数据
data_list = []
for room in room_list:
temp = {
}
temp['title'] = room.find_element_by_xpath('./a[1]/div[2]/div[1]/h3').text
temp['type'] = room.find_element_by_xpath('./a[1]/div[2]/div[1]/span').text
temp['owner'] = room.find_element_by_xpath('./a[1]/div[2]/div[2]/h2').text
temp['num'] = room.find_element_by_xpath('./a[1]/div[2]/div[2]/span').text
temp['num'] = room.find_element_by_xpath('./a[1]/div[1]/div[1]/img').get_attribute('src')
data_list.append(temp)
return data_list
def save_data(self,data_list):
for data in data_list:
print(data)
def run(self):
# 1.获取网页
self.driver.get(self.url)
# 加入循环翻页爬取更多数据
while True:
# 2.获取数据
data_list = self.parse_data()
# 3.保存数据
self.save_data(data_list)
# 翻页
try:
next = self.driver.find_elements_by_xpath('//*[contains(text(),"下一页")]')
# 下拉页面保证下一页按钮被点击
self.driver.execute_script('scrollTo(0,10000)')
next.click()
except:
break
if __name__ =="__main__":
douyu = Douyu()
douyu.run()