【Python爬虫--scrapy+selenium框架】超详细的Python爬虫scrapy+selenium框架学习笔记(保姆级别的,非常详细)

六,selenium

想要下载PDF或者md格式的笔记请点击以下链接获取
python爬虫学习笔记点击我获取
Scrapy+selenium详细学习笔记点我获取
Python超详细的学习笔记共21万字点我获取
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1,下载配置

## 安装:
pip install selenium

## 它与其他库不同的地方是他要启动你电脑上的浏览器, 这就需要一个驱动程序来辅助. 

## 这里推荐用chrome浏览器

## chrome驱动地址:

http://chromedriver.storage.googleapis.com/index.html
https://googlechromelabs.github.io/chrome-for-testing/#stable

image-20240122193411031

## 先查看自己谷歌浏览器的版本,我的是120.0.6099.255

然后打开这个驱动地址

https://googlechromelabs.github.io/chrome-for-testing/#stable

image-20240122193642372

选stable 稳定版

然后在网页上搜索我们的版本,只要前三个部分对应上就行,也就是120.0.6099

如下图,就这样我们找到了我们想要的版本

image-20240122193954470

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

image-20240122194328843

然后关键的来了. 把你下载的浏览器驱动放在python解释器所在的文件夹

Windwos: py -0p 查看Python路径

Mac: open + 路径

image-20240122195003848

到此为止配置就结束了

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_url

3.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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学网安的A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值