selenium

selenium基本使用

由于requests不能执行js,有的页面内容,我们在浏览器中可以看到,但是请求下来没有---》selenium模块:模拟操作浏览器,完成人的行为。

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题

selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器

# 安装
pip3.8 install selenium

基本使用

# 由于是驱动浏览器:需要确定好驱动哪个浏览器:ie,火狐,谷歌(推荐),下载相应的驱动
https://registry.npmmirror.com/binary.html?path=chromedriver/
浏览器版本要和驱动对应好  103.0.5060.134 下载后解压放在项目路径下

from selenium import webdriver
import time
# 第一步: 等同于你双击谷歌浏览器,打开了浏览器
bro = webdriver.Chrome(executable_path='chromedriver.exe')

bro = webdriver.Chrome()  # 不写路径,要放到项目路径或环境变量中

# 第二步:在地址栏输入地址
bro.get('http://www.baidu.com')

# 第三步:关闭浏览器
time.sleep(2)

bro.close()  # 关闭标签
bro.quit()  # 关闭浏览器

模拟登录百度

from selenium.webdriver.common.by import By
from selenium import webdriver

bro = webdriver.Chrome()
bro.implicitly_wait(10)  # 隐式等待
bro.get('https://www.baidu.com/')

# 按钮对象
# 根据标签id号,获取标签
btn=bro.find_element_by_id('s-top-loginbtn')  # 老版本
btn = bro.find_element(by=By.ID, value='s-top-loginbtn')  # 新版本
# 根据文字找标签:a标签的文字
btn2 = bro.find_element(by=By.LINK_TEXT, value='登录')

# 点击按钮
btn.click()

# 输入框对象
username = bro.find_element(by=By.ID, value='TANGRAM__PSP_11__userName')
password = bro.find_element(by=By.ID, value='TANGRAM__PSP_11__password')

# 输入文本
username.send_keys('xxxxxx')
password.send_keys('xxxxxx')

# 登录按钮
btn_login=bro.find_element(by=By.ID,value='TANGRAM__PSP_11__submit')
btn_login.click()

bro.close()  # 关闭标签

查找控件,点击,输入文本

# 查找控件:
bro.find_element(by=By.ID,value='TANGRAM__PSP_11__submit')
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    # 根据标签名
5.find_element_by_class_name  # 根据类名
6.find_element_by_name        # 根据name属性

7.find_element_by_css_selector  # css选择器
8.find_element_by_xpath         # xpath

# 点击
对象.click()

# 输入文本
对象.send_keys('内容')

无界面浏览器

不显示的打开浏览器的图形化界面,还能获取数据

import time
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下如果系统不支持可视化不加这条会启动失败

# 需要选择chrome_options
driver = webdriver.Chrome(options=chrome_options)
driver.get('https://dig.chouti.com/')

print(driver.page_source) # 打印当前页面内容

time.sleep(2)
driver.close()

selenium其它用法

获取位置属性大小,文本

import time
import base64
from selenium import webdriver
from selenium.webdriver.common.by import By

bro = webdriver.Chrome()
bro.get('https://kyfw.12306.cn/otn/resources/login.html')
bro.implicitly_wait(10)
btn = bro.find_element(By.LINK_TEXT, '扫码登录')

btn.click()
time.sleep(1)
img = bro.find_element(By.ID, 'J-qrImg')

# 获取属性
img.location
img.size
img.id
img.tag_name
img.get_attribute('src')

# 获取属性并且存入文件中
s = img.get_attribute('src')
with open('code.png', 'wb') as f:
    res = base64.b64decode(s.split(',')[-1])
    f.write(res)

bro.close()

等待元素被加载

程序操作页面非常快,所以在取每个标签的时候,标签可能没有加载号,需要设置等待

# 隐式等待
bro.implicitly_wait(10)

元素操作

# 搜索标签:
find_element:找第一个      
find_elements:找所有
    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    # 根据标签名
    5.find_element_by_class_name  # 根据类名
    6.find_element_by_name        # 根据name属性
    7.find_element_by_css_selector  # css选择器
    8.find_element_by_xpath         # xpath
    
# 点击
标签.click()

# 文本输入
标签.send_keys()

# 清空
标签.clear()

# 滑动到屏幕底部
bro.execute_script('scrollTo(0,document.body.scrollHeight)')

执行js代码

import time
from selenium import webdriver
bro = webdriver.Chrome()

bro.get('https://www.pearvideo.com/category_8')
time.sleep(1)

# js代码
bro.execute_script('scrollTo(0,document.body.scrollHeight)')
bro.execute_script('alert(md5_vm_test())')

time.sleep(1)
bro.close()

# 执行js用途
1.普通滑屏,打开新标签   
2.可以执行js代码,别人网站的变量,函数,都可以拿到并执行的

切换选项卡

import time
from selenium import webdriver
from selenium.webdriver.common.by import By

bro = webdriver.Chrome()

bro.get('https://www.pearvideo.com/category_8')

bro.execute_script('window.open()')
# bro.switch_to_window(bro.window_handles[1])  老版本,弃用了
bro.switch_to.window(bro.window_handles[1])
bro.get('http://www.baidu.com')
bro.switch_to.window(bro.window_handles[0])


# 关闭选项卡
bro.close()

# 关闭浏览器
bro.quit()

浏览器前进后退

from selenium import webdriver

bro = webdriver.Chrome()

bro.get('https://www.pearvideo.com/category_8')
bro.get('https://www.baidu.com')

# 后退
bro.back()
# 前进
bro.forward()

bro.quit()

异常处理

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException, NoSuchFrameException
bro = webdriver.Chrome()


try:
    bro.get('https://www.pearvideo.com/category_8')
    time.sleep(1)
    bro.get('https://www.baidu.com')

    bro.back()
    raise Exception('报错')
    # 下面不会执行
    time.sleep(1)
    bro.forward()
except Exception as e:
    print(e)
finally:
    bro.quit()

selenium登录cnblogs获取cookie

获取cookie

import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By

bro = webdriver.Chrome()
bro.implicitly_wait(10)

try:
    bro.get('https://www.cnblogs.com/')
    time.sleep(1)
    btn = bro.find_element(By.LINK_TEXT, '登录')
    btn.click()
    time.sleep(3)
    username = bro.find_element(By.ID, 'mat-input-0')
    password = bro.find_element(By.ID, 'mat-input-1')
    username.send_keys('1814096942@qq.com')
    time.sleep(1)
    password.send_keys('yyq123456')

    btn_login = bro.find_element(By.CSS_SELECTOR,
                                 'body > app-root > app-sign-in-layout > div > div > app-sign-in > app-content-container > div > div > div > form > div > button')
    btn_login.click()
    # time.sleep(20) # 人工破解验证码,登录成功
    input()  # 需要在控制台回车
    cookies = bro.get_cookies()
    print(cookies)
    with open('cnblgos.json', 'w', encoding='utf-8') as f:
        json.dump(cookies, f)

    time.sleep(2)

except Exception as e:
    print(e)

finally:
    bro.quit()

打开页面

import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By

bro = webdriver.Chrome()
bro.implicitly_wait(10)

try:
    bro.get('https://www.cnblogs.com/')
    time.sleep(2)
    # 把cookie写入浏览器,刷新一下,就登录了
    with open('cnblgos.json', 'r', encoding='utf-8') as f:
        res = json.load(f)
    for item in res:
        bro.add_cookie(item)

    # 刷新浏览器
    bro.refresh()
    time.sleep(2)

except Exception as e:
    print(e)

finally:
    bro.quit()

抽屉新热榜半自动点赞

from bs4 import BeautifulSoup
from selenium.webdriver.chrome.options import Options
import json
from selenium import webdriver
import requests

# 修改cookie为requests的格式
with open('chouti.json', 'r', encoding='utf-8')as f:
    res = json.load(f)
cookies = {}
for i in res:
    cookies[i['name']] = i['value']
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
    "Referer": "https://dig.chouti.com/"
}

# 无界面浏览器
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(options=chrome_options)
bro.implicitly_wait(10)

try:
    bro.get('https://dig.chouti.com/')
    # 把cookie写入浏览器,刷新一下,就登录了
    with open('chouti.json', 'r', encoding='utf-8') as f:
        res = json.load(f)
    for item in res:
        bro.add_cookie(item)
    bro.refresh()  # 刷新
    # 获取页面内容
    soup = BeautifulSoup(bro.page_source, 'html.parser')
    # 筛选出id
    id_list = soup.find_all(class_="link-title link-statistics")
    # for循环发送请求
    for i in id_list:
        id = i['data-id']
        requests.post('https://dig.chouti.com/link/vote', headers=header, cookies=cookies, data={"linkId": id})

except Exception as e:
    print(e)

finally:
    bro.quit()

动作链

from selenium import webdriver
from selenium.webdriver import ActionChains
import time
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
driver.implicitly_wait(10)

driver.maximize_window()

try:
    driver.switch_to.frame('iframeResult')
    sourse = driver.find_element(By.ID, 'draggable')
    target = driver.find_element(By.ID, 'droppable')

# 方式一:基于同一个动作链串行执行
    actions = ActionChains(driver)
    # 平行移动等于解锁的长度的距离
    actions.drag_and_drop(sourse, target)
    actions.perform()

    actions = ActionChains(driver).click_and_hold(sourse)
    # 平行移动大于解锁的长度的距离
    actions.drag_and_drop_by_offset(target, 10, 20)
    actions.perform()

# 方式二:不同的动作链,每次移动的位移都不同
    ActionChains(driver).click_and_hold(sourse).perform()
    distance = target.location['x'] - sourse.location['x']  # 两个控件的x轴的距离
    track = 0
    while track < distance:
        ActionChains(driver).move_by_offset(xoffset=4, yoffset=0).perform()
        track += 2
    ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform()
    ActionChains(driver).release().perform()

    time.sleep(10)

finally:
    driver.close()
    
    
'''--------------实例------------'''
ActionChains(driver).move_by_offset(xoffset=2,yoffset=0).perform()  # 滑块,滑动验证码的破解
actions.drag_and_drop_by_offset(target,10,20)  # 原来的12306的点选,cnblgs选出所有红绿灯的验证码
         actions=ActionChains(driver)
         actions.drag_and_drop_by_offset(target,10,20)

xpath的使用

一般解析库都会有子的的搜索标签的方法,一般都会支持cssxpath,XPath 是用于在 XML 文档中查找信息

表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取(取子节点)。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置(取子孙节点)。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。
div 选取div标签
# 也可以直接打开浏览器复制
//*[@id="content"]/table[3]/tbody/tr[1]/th[1]

打码平台使用

简单的数字字母组合可以使用图像识别(python 现成模块),成功率不高
使用第三方打码平台(破解验证码平台),花钱,把验证码图片给它,它给你识别完,返回给你(云打码,超级鹰)

from selenium import webdriver
from selenium.webdriver.common.by import By
from PIL import Image

bro = webdriver.Chrome()
bro.get('http://www.chaojiying.com/user/login/')
bro.maximize_window()

try:
    bro.save_screenshot('main.png')  # 把当前页面截图截图
    img = bro.find_element(By.XPATH, '/html/body/div[3]/div/div[3]/div[1]/form/div/img')
    location = img.location
    size = img.size
    print(location)
    print(size)
    # 使用pillow扣除大图中的验证码
    img_tu = (
    int(location['x']), int(location['y']), int(location['x'] + size['width']), int(location['y'] + size['height']))
    # # 抠出验证码
    # #打开
    img = Image.open('./main.png')
    # 抠图
    fram = img.crop(img_tu)
    # 截出来的小图
    fram.save('code.png')
    from chaojiying import ChaojiyingClient

    chaojiying = ChaojiyingClient('306334678', 'lqz12345', '937234')
    im = open('a.jpg', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    print(chaojiying.PostPic(im, 1902))

except:
    pass
finally:
    bro.close()
posted @ 2022-08-02 21:52  Rain_Kz  阅读(42)  评论(0编辑  收藏  举报