4.selenium
1 selenium介绍和快速使用
# web自动化测试工具---》自动操作浏览器,模拟人的行为---》通过代码控制完成本来应该人完成的功能
# appnium:app端爬虫,app的自动化测试
# 解决requests不能执行js的问题---》使用requests发送请求,获取到的数据跟实际浏览器看到的数据有差距---》原因是有部分数据是通过ajax加载并渲染的---》selenium因为是直接操作浏览器--》自动的执行js---》真正的实现可见即可爬---》拿到的数据跟在浏览器看到的是一样
## 使用---》下载模块
pip3 install selenium
## 使用----》浏览器驱动---》不通浏览器不一样---》selenium是通过代码操作浏览器驱动来实现操作浏览器的目的---》谷歌浏览器为例(其他浏览器也没问题--》需要下相关浏览器的驱动)---》浏览器版本要跟驱动版本一一对应
https://registry.npmmirror.com/binary.html?path=chromedriver/
# 我的版本:99.0.4844.51----》
from selenium import webdriver
import time
# 相当于我们打开了谷歌浏览器,双击打开了,bro就是浏览器对戏
bro=webdriver.Chrome(executable_path='./chromedriver')
# bro=webdriver.Chrome(executable_path='chromedriver.exe') # win
# 在地址栏输入地址,访问
bro.get('https://www.baidu.com')
time.sleep(3)
bro.close() # 关闭浏览器
1.1 模拟登陆百度
# 先用3.x版本
from selenium import webdriver
import time
bro=webdriver.Chrome(executable_path='./chromedriver')
bro.get('http://www.baidu.com')
time.sleep(1)
### 操作百度---》搜索
## 选择器--》找到输入框-->对象
# input_search=bro.find_element_by_id('kw')
# ## 向输入框中写文字
# input_search.send_keys("美女")
# ## 找到按钮---》点击
# button_submit=bro.find_element_by_id('su')
# button_submit.click()
# time.sleep(10)
# bro.close()
### 模拟登陆一下
# 加入隐士等待-->如果标签找不到,就等待--》直到等10s还没加载好,就报错
bro.implicitly_wait(10)
# 找到登陆按钮---》可以通过id找---》还可以通过a标签的内容找
submit_a=bro.find_element_by_link_text('登录')
submit_a.click()
# 找到账号登陆,点击
username_login=bro.find_element_by_id('TANGRAM__PSP_11__changePwdCodeItem')
username_login.click()
# 在用户名和密码输入框中输入内容
username=bro.find_element_by_id('TANGRAM__PSP_11__userName')
password=bro.find_element_by_id('TANGRAM__PSP_11__password')
username.send_keys("306334689@qq.com")
password.send_keys("lxsdafdsasd")
time.sleep(3)
submit=bro.find_element_by_id('TANGRAM__PSP_11__submit')
submit.click()
# 很大概率会出现滑块---》手动操作---》自动操作(麻烦一些)
# 你自动登陆的目的是什么----》只是为了拿到cookie--》获取数据
# 如果一个网站登陆功能特别麻烦---》半手动操作---》拿到cookie后在自动操作---》cookie池
# 这个地方进行手动操作
time.sleep(5)
bro.close()
1.1 无界面浏览器
# 请求头中的客户端信息和referer和cookie都是自动处理的
# 某个参数控制---》浏览器没有可视化界面---》进程还在---》
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 实例化得到一个配置对象
chrome_options = Options()
chrome_options.add_argument('window-size=1920x3000') #指定浏览器分辨率
chrome_options.add_argument('--disable-gpu') #谷歌文档提到需要加上这个属性来规避bug
chrome_options.add_argument('--hide-scrollbars') #隐藏滚动条, 应对一些特殊页面
chrome_options.add_argument('blink-settings=imagesEnabled=false') #不加载图片, 提升速度
chrome_options.add_argument('--headless') #浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
bro=webdriver.Chrome(executable_path='./chromedriver',chrome_options=chrome_options)
bro.get('http://www.baidu.com')
# 把加载后的页面内容打印出来--->html(render和ajax渲染完成的)---》可见即可得
print(bro.page_source)
with open('baidu.html','w',encoding='utf-8') as f:
f.write(bro.page_source)
bro.close()
## 使用requets发送请求
# import requests
# res=requests.get('http://www.baidu.com')
# print(res.text)
2 选择器
2.1 基本使用
# 在html中查找内容的方式
# bs4有选择器:自己的 find和find_all,css选择器
# 所有解析库:有自己的解析器,还支持 css选择器和xpath选择器
'''
# 自己的
# 1、find_element_by_id # 通过标签id找
# 2、find_element_by_link_text # 通过a标签的内容找
# 3、find_element_by_partial_link_text # 通过a标签的内容找,模糊匹配
# 4、find_element_by_tag_name # 通过标签名 body div
# 5、find_element_by_class_name # 通过类名
# 6、find_element_by_name # 标签的name属性找
# css和xpath
# 7、find_element_by_css_selector # 通过css选择器找
# 8、find_element_by_xpath # 通过xpath找
# 还有find_elements系列---》找所有
'''
# from bs4 import BeautifulSoup
# from selenium import webdriver
# bro=webdriver.Chrome(executable_path='./chromedriver')
# bro.get('https://www.cnblogs.com/')
# bro.implicitly_wait(10)
# # 你也可以这样=-----》结合bs4使用
# # print(bro.page_source)
# # soup=BeautifulSoup(bro.page_source,'lxml')
# # soup.find('')
#
#
# # title_list=bro.find_elements_by_class_name('post-item-title')
#
# '''
# .类名
# #id
# 标签名
# 标签名 标签名
# 标签名>标签名
#
# '''
# title_list=bro.find_elements_by_css_selector('a.post-item-title')
# print(title_list)
#
# bro.close()
### xpath选择器
2.2 xpath
# XPath 使用路径表达式来选取 XML 文档中的节点或节点集
'''
* 表示任意标签
/div 查找当前路径下的div标签
//div 查找当前路径下子子孙孙的div标签
@src='xx' 获取属性
./ 从当前路径下找
../ 从上一层开始找
text() 获取文本内容
'''
# 在html中查找内容的方式
# bs4有选择器:自己的 find和find_all,css选择器
# 所有解析库:有自己的解析器,还支持 css选择器和xpath选择器
'''
# 自己的
# 1、find_element_by_id # 通过标签id找
# 2、find_element_by_link_text # 通过a标签的内容找
# 3、find_element_by_partial_link_text # 通过a标签的内容找,模糊匹配
# 4、find_element_by_tag_name # 通过标签名 body div
# 5、find_element_by_class_name # 通过类名
# 6、find_element_by_name # 标签的name属性找
# css和xpath
# 7、find_element_by_css_selector # 通过css选择器找
# 8、find_element_by_xpath # 通过xpath找
# 还有find_elements系列---》找所有
'''
# from bs4 import BeautifulSoup
# from selenium import webdriver
# bro=webdriver.Chrome(executable_path='./chromedriver')
# bro.get('https://www.cnblogs.com/')
# bro.implicitly_wait(10)
# # 你也可以这样=-----》结合bs4使用
# # print(bro.page_source)
# # soup=BeautifulSoup(bro.page_source,'lxml')
# # soup.find('')
#
#
# # title_list=bro.find_elements_by_class_name('post-item-title')
#
# '''
# .类名
# #id
# 标签名
# 标签名 标签名
# 标签名>标签名
#
# '''
# title_list=bro.find_elements_by_css_selector('a.post-item-title')
# print(title_list)
#
# bro.close()
### xpath选择器
2.3 获取标签属性
from selenium import webdriver
import time
bro=webdriver.Chrome(executable_path='./chromedriver')
bro.get('https://www.cnblogs.com/')
# 找到标签---》自带的,css,xpath选择---》get_attribute获取属性
# title=bro.find_element_by_xpath('//*[@id="post_list"]/article[1]/section/div/a').get_attribute('href')
title=bro.find_element_by_xpath('//*[@id="post_list"]/article[1]/section/div/p')
# print(title)
print(title.id) # 该id不是标签的id,而是selenium的id,没有意义
print(title.location) # x,y轴
print(title.tag_name) # 标签名字
print(title.size) # 大小
## 最重要的
print(title.text) # 文本内容
print(title.get_attribute('href')) # 获取属性
# 需要借助pillow,从页面中把头像截取出来
'''
print(tag.get_attribute('src'))
#获取标签ID,位置,名称,大小(了解)
print(tag.id)
print(tag.location)
print(tag.tag_name)
print(tag.size)
'''
time.sleep(3)
bro.close()
2.4 等待加载和元素交互
from selenium import webdriver
import time
bro=webdriver.Chrome(executable_path='./chromedriver')
bro.get('https://www.cnblogs.com/')
# 通过代码操作浏览器,速度非常快---》标签可能还没加载完,获取不到就报错---》显示等待,隐士等待
# 隐士等待--->页面中,要找所有标签,如果找不到就会一直等待直到找到或者到10s时间
bro.implicitly_wait(10)
### 点击,清空,写文字
# 标签.click()
# 标签.clear()
# 标签.send_keys("文字")
time.sleep(3)
bro.close()
3 其他操作
3.1 前进后退
import time
from selenium import webdriver
browser=webdriver.Chrome(executable_path='./chromedriver')
browser.get('https://www.baidu.com')
browser.get('https://www.taobao.com')
browser.get('http://www.sina.com.cn/')
browser.back()
time.sleep(3)
browser.forward()
browser.close()
3.2 cookie处理
from selenium import webdriver
import time
import json
# 假设我现在登陆到了一个网站----》把cookie存到本地---》下次我再打开这个网站--》把本地的cookie写进去-->我就是登陆状态
# 半自动登陆到cnblogs---》滑块--》cookie保存到本地
# 再打开cnblogs---》把之前的cookie写入--》现在就是登陆状态
# 使用selenium登陆网站---》拿到cookie,使用requests发送请求
# browser=webdriver.Chrome(executable_path='./chromedriver')
# browser.get('https://account.cnblogs.com/signin?returnUrl=https:%2F%2Fwww.cnblogs.com%2F')
# username=browser.find_element_by_xpath('//*[@id="mat-input-0"]')
# # username=browser.find_element_by_id('mat-input-0')
# password=browser.find_element_by_id('mat-input-1')
# username.send_keys("616564099@qq.com")
# password.send_keys('sdfasfadsfaasdf')
# # 暂停一会,手动操作
# input("请确认是否准备好了:")
#
#
#
# print(browser.get_cookies())
#
# with open('cnblogs.json','w',encoding='utf-8') as f:
# json.dump(browser.get_cookies(),f)
#
# time.sleep(3)
# browser.close()
## 再访问首页
# browser=webdriver.Chrome(executable_path='./chromedriver')
# browser.get('https://www.cnblogs.com/')
# with open('cnblogs.json','r',encoding='utf-8') as f:
# cookies=json.load(f)
# for cookie in cookies:
# browser.add_cookie(cookie)
#
# # 刷新页面
# browser.refresh()
# time.sleep(5)
#
# browser.close()
## 使用selenium半自动登陆拿到cookie,使用requests发送请求-
# 某网站自动点赞
# 自动登录12306---》验证码没了---》只有滑块了
-滑块,验证码破解
3.4 执行js
from selenium import webdriver
import time
browser=webdriver.Chrome(executable_path='./chromedriver')
browser.get('https://www.cnblogs.com/')
# 可以直接在页面中执行js---》取出该页面中的某些变量--》取出cookie传到某个服务器
# browser.execute_script('alert(1)')
# 滑动屏幕--》把屏幕滑到低---》再加载下一页
browser.execute_script('window.scrollTo(0,document.body.scrollHeight);')
time.time(3)
browser.close()
3.5 选项卡管理
import time
from selenium import webdriver
browser=webdriver.Chrome(executable_path='./chromedriver')
browser.get('https://www.baidu.com')
browser.execute_script('window.open()')
print(browser.window_handles) #获取所有的选项卡
# browser.switch_to_window(browser.window_handles[1])
browser.switch_to.window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(5)
browser.switch_to.window(browser.window_handles[0])
browser.get('https://www.sina.com.cn')
browser.close()
3.6 异常捕获
import time
from selenium import webdriver
browser=webdriver.Chrome(executable_path='./chromedriver')
browser.get('https://www.baidu.com')
try:
browser.execute_script('window.open()')
except Exception as e:
print(e)
finally:
browser.close()
4 项目练习
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys #键盘按键操作
bro=webdriver.Chrome(executable_path='./chromedriver')
def get_goods(bro):
li_list=bro.find_elements_by_class_name('gl-item')
for li in li_list:
try:
# 获取图片地址
img=li.find_element_by_css_selector('div.p-img img').get_attribute('src')
if not img:
img='http:'+li.find_element_by_css_selector('div.p-img img').get_attribute('data-lazy-img')
title=li.find_element_by_css_selector('div.p-name a').text
price=li.find_element_by_css_selector('div.p-price i').text
url=li.find_element_by_css_selector('div.p-img a').get_attribute('href')
commit=li.find_element_by_css_selector('div.p-commit a').text
print('''
商品名字:%s
商品地址:%s
商品价格:%s
商品图片:%s
商品评论:%s
'''%(title,url,price,img,commit))
except Exception as e:
continue
# 点击下一页继续加载
next=bro.find_element_by_partial_link_text('下一页')
time.sleep(1)
next.click()
get_goods(bro) # 递归调用---》最大递归深度---》58--》抛异常
try:
bro.get('https://www.jd.com/')
bro.implicitly_wait(10)
input_search=bro.find_element_by_id('key')
input_search.send_keys("精品内衣")
input_search.send_keys(Keys.ENTER) # 模拟人敲回车
get_goods(bro)
except Exception as e:
print(e)
finally:
bro.close()