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()

 

 

 

 

 

 

 

posted @ 2022-03-18 20:01  甜甜de微笑  阅读(53)  评论(0编辑  收藏  举报