12.selenium
12.selenium
1,下载配置
## 安装:
pip install selenium
## 它与其他库不同的地方是他要启动你电脑上的浏览器, 这就需要一个驱动程序来辅助.
## 这里推荐用chrome浏览器
## chrome驱动地址:
http://chromedriver.storage.googleapis.com/index.html
https://googlechromelabs.github.io/chrome-for-testing/#stable
## 先查看自己谷歌浏览器的版本,我的是120.0.6099.255然后打开这个驱动地址
https://googlechromelabs.github.io/chrome-for-testing/#stable

选 stable 稳定版
然后在网页上搜索我们的版本,只要前三个部分对应上就行,也就是 120.0.6099
如下图,就这样我们找到了我们想要的版本

把 URL 地址复制下载去浏览器下载驱动

下完以后解压,发现里面是个 exe 文件(往后浏览器更新了,驱动也需要重新下载对应版本的)

然后关键的来了. 把你下载的浏览器驱动放在 python 解释器所在的文件夹
Windwos: py -0p 查看 Python 路径
Mac: open + 路径

到此为止配置就结束了
2,selenium 导入使用
from selenium.webdriver import Chrome # 导入谷歌浏览器的类
# 创建浏览器对象
web = Chrome() # 如果你的浏览器驱动放在了解释器文件夹
web.get("http://www.baidu.com") # 输入网址2、selenium 的基本使用
2.1 加载网页:
selenium 通过控制浏览器,所以对应的获取的数据都是 elements 中的内容
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 访问百度
driver.get("http://www.baidu.com/")
# 截图
driver.save_screenshot("baidu.png")2.2 定位和操作:
# 搜索关键字 杜卡迪
driver.find_element(By.ID, "kw").send_keys("杜卡迪")
# 点击id为su的搜索按钮
driver.find_element(By.ID, "su").click()3.3 查看请求信息:
driver.page_source # 获取页面内容
driver.get_cookies()
driver.current_url3.4 退出
driver.close() # 退出当前页面
driver.quit() # 退出浏览器3.5 小结
1. selenium的导包:
from selenium import webdriver
2. selenium创建driver对象:
driver = webdriver.Chrome()
3. selenium请求数据:
driver.get("http://www.baidu.com/")
4. selenium查看数据:
driver.page_source
5. 关闭浏览器:
driver.quit()
6. 根据id定位元素:
driver.find_element_by_id("kw")/driver.find_element(By.ID, "kw")
7. 操作点击事件:
click()
8. 给输入框赋值:
send_keys()
9,获取cookie:
driver.get_cookies()
10,刷新页面
driver.refresh()
11,执行js代码
driver.execute_script(f'window.scrollBy(0, {step_length})')3-6 小案例
3-6-1 简单案例
找到搜索框,输入内容,找到搜索按钮进行点击
import time
from selenium.webdriver import Chrome # 导入谷歌浏览器的类
# 创建浏览器对象
from selenium.webdriver.common.by import By
web = Chrome() # 如果你的浏览器驱动放在了解释器文件夹
web.get("https://www.gushiwen.cn/") # 输入网址
# 查找搜索框
txtKey = web.find_element(By.ID,'txtKey')
txtKey.send_keys('唐诗')
# 找到点击按钮
search = web.find_element(By.XPATH,'//*[@id="search"]/form/input[3]')
search.click()
print(search)
time.sleep(5)
web.quit()3-6-2 解决登录问题
2-1 基本代码
import time
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
driver = Chrome()
# 访问的网址
driver.get('https://www.gushiwen.cn/')
"""
1 点击我的 到登录页面
2 获取账号节点 输入值
3 获取密码节点 输入值
4 获取验证码节点 输入值
5 点击登录
"""
# 点我的
driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/div/div[2]/div/a[6]').click()
# 获取账号节点
email = driver.find_element(By.ID, 'email')
email.send_keys('793390457@qq.com')
# 获取密码节点
password = driver.find_element(By.ID, 'pwd')
password.send_keys('xlg17346570232')
# 获取验证码节点
yzm = driver.find_element(By.ID, 'code')
yzm.send_keys('1234')
time.sleep(5)
# 点击登录
driver.find_element(By.ID, 'denglu').click()
time.sleep(5)2-2 打码平台
import base64
import json
import requests
import time
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
def base64_api(uname, pwd, img, typeid):
with open(img, 'rb') as f:
base64_data = base64.b64encode(f.read())
b64 = base64_data.decode()
data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64}
result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)
if result['success']:
return result["data"]["result"]
else:
#!!!!!!!注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别
return result["message"]
return ""
if __name__ == "__main__":
driver = Chrome()
# 访问的网址
driver.get('https://www.gushiwen.cn/')
"""
1 点击我的 到登录页面
2 获取账号节点 输入值
3 获取密码节点 输入值
4 获取验证码节点 输入值
5 点击登录
"""
# 点我的
driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/div/div[2]/div/a[6]').click()
# 获取账号节点
email = driver.find_element(By.ID, 'email')
email.send_keys('793390457@qq.com')
# 获取密码节点
password = driver.find_element(By.ID, 'pwd')
password.send_keys('xlg17346570232')
# 验证码图片的节点
img_path = "yzm.jpg"
# screenshot截图并保存保存
driver.find_element(By.ID, 'imgCode').screenshot(img_path)
# 识别验证码
result = base64_api(uname='luckyboyxlg', pwd='17346570232', img=img_path, typeid=3)
print(result)
# 获取验证码节点
yzm = driver.find_element(By.ID, 'code')
yzm.send_keys(result) # 输入识别后的值
time.sleep(8)
# 点击登录
driver.find_element(By.ID, 'denglu').click()
time.sleep(50)2-3 保存登录后的 cookie
import base64
import json
import requests
import time
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
def base64_api(uname, pwd, img, typeid):
with open(img, 'rb') as f:
base64_data = base64.b64encode(f.read())
b64 = base64_data.decode()
data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64}
result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)
if result['success']:
return result["data"]["result"]
else:
#!!!!!!!注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别
return result["message"]
return ""
if __name__ == "__main__":
driver = Chrome()
# 访问的网址
driver.get('https://www.gushiwen.cn/')
"""
1 点击我的 到登录页面
2 获取账号节点 输入值
3 获取密码节点 输入值
4 获取验证码节点 输入值
5 点击登录
"""
# 点我的
driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/div/div[2]/div/a[6]').click()
# 获取账号节点
email = driver.find_element(By.ID, 'email')
email.send_keys('793390457@qq.com')
# 获取密码节点
password = driver.find_element(By.ID, 'pwd')
password.send_keys('xlg17346570232')
# 验证码图片的节点
img_path = "yzm.jpg"
# screenshot截图并保存保存
driver.find_element(By.ID, 'imgCode').screenshot(img_path)
# 识别验证码
result = base64_api(uname='luckyboyxlg', pwd='17346570232', img=img_path, typeid=3)
print(result)
# 获取验证码节点
yzm = driver.find_element(By.ID, 'code')
yzm.send_keys(result) # 输入识别后的值
time.sleep(8)
# 点击登录
driver.find_element(By.ID, 'denglu').click()
time.sleep(4)
# 获取cookie保存到本地
cookies = driver.get_cookies()
print(cookies)
with open('cookies.txt', 'w', encoding='UTF-8') as f:
f.write(json.dumps(cookies))2-4 携带 cookie 进行访问
import time
from selenium.webdriver.common.by import By
from selenium.webdriver import Chrome
import json
driver = Chrome()
# 访问登录
driver.get('https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx')
# 本地cookie加载
with open('cookies.txt', 'r', encoding='UTF-8') as f:
cookies = json.loads(f.read())
# cookie加载到selenium中
for cookie in cookies:
driver.add_cookie(cookie)
# 刷新一下
driver.refresh()
driver.get('https://so.gushiwen.cn/user/collect.aspx')
time.sleep(10)3-6-3 抓取网易
import time
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
def window_scroll(driver, stop_length, step_length):
'''
向下滚动方法封装
:param driver: selenium对象
:param stop_length: 滚动终止值
:param step_length: 每次滚动步长
:return:
'''
while True:
# 终止不滚的条件
if stop_length - step_length <= 0:
driver.execute_script(f'window.scrollBy(0, {stop_length})')
break
# 执行js代码 向下滚动
driver.execute_script(f'window.scrollBy(0, {step_length})')
stop_length -= step_length
time.sleep(1) # 1秒滚一下
# driver.execute_script('window.scrollBy(0, 30000)')
if __name__ == '__main__':
driver = Chrome()
driver.get('https://news.163.com/')
stop_length = 30000 # 终止值
step_length = 2000 # 每次滚动的值
# 循环5次点击加载更多
for i in range(1, 6):
window_scroll(driver, stop_length, step_length)
# 点击加载更多
more = driver.find_element(By.XPATH, '//*[@id="index2016_wrap"]/div[3]/div[2]/div[3]/div[2]/div[5]/div/a[3]/div[1]/span')
# more.click() # 点击
driver.execute_script('arguments[0].click()', more)
print(f'第:{i}次 点击加载更多')
time.sleep(5)
# 获取页面所有源代码
page = driver.page_source
print(page)3、selenium 的定位操作
1,元素定位的两种写法:
直接调用型
el = driver.find_element_by_xxx(value) # xxx是定位方式,后面我们会讲,value为该方式对应的值使用 By 类型(需要导入 By) 建议使用这种方式
# 直接掉用的方式会在底层翻译成这种方式 from selenium.webdriver.common.by import By driver.find_element(By.xxx,value)
2,元素定位的两种方式:
精确定位一个元素,返回结果为一个 element 对象,定位不到则报错
driver.find_element(By.xx, value) # 建议使用 driver.find_element_by_xxx(value)定位一组元素,返回结果为 element 对象列表,定位不到返回空列表
driver.find_elements(By.xx, value) # 建议使用 driver.find_elements_by_xxx(value)
3,元素定位的八种方法:
以下方法在 element 之后添加 s 就变成能够获取一组元素的方法
By.ID 使用 id 值定位
el = driver.find_element(By.ID, '') el = driver.find_element_by_id()By.XPATH 使用 xpath 定位
el = driver.find_element(By.XPATH, '') el = driver.find_element_by_xpath()By.TAG_NAME. 使用标签名定位
el = driver.find_element(By.TAG_NAME, '') el = driver.find_element_by_tag_name()By.LINK_TEXT 使用超链接文本定位
el = driver.find_element(By.LINK_TEXT, '') el = driver.find_element_by_link_text()By.PARTIAL_LINK_TEXT 使用部分超链接文本定位
el = driver.find_element(By.PARTIAL_LINK_TEXT , '') el = driver.find_element_by_partial_link_text()By.NAME 使用 name 属性值定位
el = driver.find_element(By.NAME, '') el = driver.find_element_by_name()By.CLASS_NAME 使用 class 属性值定位
el = driver.find_element(By.CLASS_NAME, '') el = driver.find_element_by_class_name()By.CSS_SELECTOR 使用 css 选择器定位
el = driver.find_element(By.CSS_SELECTOR, '') el = driver.find_element_by_css_selector()
注意:
find_element 与 find_elements 区别
1. 只查找一个元素的时候:可以使用find_element(),find_elements()
find_element()会返回一个WebElement节点对象,但是没找到会报错,而find_elements()不会,之后返回一个空列表
2. 查找多个元素的时候:只能用find_elements(),返回一个列表,列表里的元素全是WebElement节点对象
3. 找到都是节点(标签)
4. 如果想要获取相关内容(只对find_element()有效,列表对象没有这个属性) 使用 .text
5. 如果想要获取相关属性的值(如href对应的链接等,只对find_element()有效,列表对象没有这个属性):使用 .get_attribute("href")
4、元素的操作
find_element_by_xxx 方法仅仅能够获取元素对象,接下来就可以对元素执行以下操作 从定位到的元素中提取数据的方法
4.1 从定位到的元素中获取数据
el.get_attribute(key) # 获取key属性名对应的属性值
el.text # 获取开闭标签之间的文本内容4.2 对定位到的元素的操作
el.click() # 对元素执行点击操作
el.submit() # 对元素执行提交操作
el.clear() # 清空可输入元素中的数据
el.send_keys(data) # 向可输入元素输入数据5,小结
## 1. 根据xpath定位元素:
driver.find_elements(By.XPATH,"//*[@id='s']/h1/a")
## 2. 根据class定位元素:
driver.find_elements(By.CLASS_NAME, "box")
## 3. 根据link_text定位元素:
driver.find_elements(By.LINK_TEXT, "下载豆瓣 App")
## 4. 根据tag_name定位元素:
driver.find_elements(By.TAG_NAME, "h1")
## 5. 获取元素文本内容:
element.text
## 6. 获取元素标签属性:
element.get_attribute("href")
## 7. 向输入框输入数据:
element.send_keys(data)4、无头浏览器
我们已经基本了解了 selenium 的基本使用了. 但是呢, 不知各位有没有发现, 每次打开浏览器的时间都比较长. 这就比较耗时了. 我们写的是爬虫程序. 目的是数据. 并不是想看网页. 那能不能让浏览器在后台跑呢? 答案是可以的
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
opt = Options()
opt.add_argument("--headless")
opt.add_argument('--disable-gpu')
opt.add_argument("--window-size=4000,1600") # 设置窗口大小
web = Chrome(options=opt)from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
opt = Options()
opt.add_argument("--headless")
opt.add_argument('--disable-gpu')
web = Chrome(options=opt)
web.get('https://www.baidu.com')
print(web.title)5、selenium 处理 cookie
通过driver.get_cookies()能够获取所有的 cookie
获取 cookie
dictCookies = driver.get_cookies()设置 cookie
driver.add_cookie(dictCookies)删除 cookie
#删除一条cookie driver.delete_cookie("CookieName") # 删除所有的cookie driver.delete_all_cookies()
6,其他知识
6.1 当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下:
alert = driver.switch_to_alert()6.2 页面前进和后退
driver.forward() # 前进
driver.back() # 后退
driver.refresh() # 刷新
driver.close() # 关闭当前窗口6.3 设置浏览器最大窗口
driver.maximize_window() #最大化浏览器窗口