爬虫学习--18.反爬斗争 selenium(3)

2024-06-01 10:36

本文主要是介绍爬虫学习--18.反爬斗争 selenium(3),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

操作多窗口与页面切换

  • 有时候窗口中有很多子tab页面。这时候肯定是需要进行切换的。selenium提供了一个叫做switch_to.window来进行切换,具体切换到哪个页面,可以从driver.window_handles中找到。

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

# 加载驱动
driver = webdriver.Chrome()

# 拿到目标url # 这个时候发现同时拿到两个url 不能够打开两个窗口
# 访问百度
driver.get("https://www.baidu.com")
# driver.get("https://www.douban.com")
time.sleep(2)

# 访问豆瓣
driver.execute_script("window.open('https://www.douban.com')")
time.sleep(2)

# driver.close()  # 此时发现百度被关闭了
# 检测当前驱动执行的url
print(driver.current_url)
# # 那这个时候我们操作多窗口防护变了没有了意义 因为我们只能操作第一个百度 那这个时候我就可以切换一下界面
# # 切换界面
driver.switch_to.window(driver.window_handles[1])
# # [1] 0代表的第一个最开始打开的那个 1代表的第二个  -1切换到最新打开的窗口   -2 倒数第二个打开的窗口
print(driver.current_url)  # 检测看是否切换到豆瓣的url了
time.sleep(1)
# driver.switch_to.window(driver.window_handles[0])
# time.sleep(1)
# # 检测看是否能对百度进行操作
# driver.find_element(By.ID,"kw").send_keys("python")

# 切换iframe
login_iframe = driver.find_element(By.XPATH,'//*[@id="anony-reg-new"]/div/div[1]/iframe')
driver.switch_to.frame(login_iframe)
time.sleep(2)
# 1 切换登录方式 定位到 密码登录(但是在这一步操作之前 要确实是否要切换iframe)
driver.find_element(By.CLASS_NAME,"tab-start").click()
time.sleep(2)
# 2 输入账号和密码
user_input = driver.find_element(By.ID,"username").send_keys("123456789")
time.sleep(2)
pwd_input = driver.find_element(By.ID,"password").send_keys("123456789")
time.sleep(2)
# 3 点击登录豆瓣
# 定位登录按钮点击 我们在定位元素的时候 如果属性出现空格的状态 形如:btn btn-account
# 解决方式 第一种我们选择属性当中的一部分(需要测试)
driver.find_element(By.CLASS_NAME,'btn-account').click()
time.sleep(3)

Selenium执行js语法

有时候selenium提供的方法会出现一些问题,或者执行起来非常麻烦,我们就可以考虑通过selenium执行javascript来实现,使复杂的操作简单化。 selenium执行js脚本的方法:

execute_script(script, *args)
描述:用来执行js语句
参数:
script:待执行的js语句,如果有多个js语句,使用英文分号;连接

常见selenium下执行js代码

1 滚动页面:您可以使用 JavaScript 滚动网页以将元素显示在视图中或在页面上移动
driver.execute_script('window.scrollTo(0,document.body.scrollHeight)') 

2 js点击: 
button = driver.find_element(By.CLASS_NAME),'my-button')
driver.execute_script("arguments[0].click();", button)

3 等待元素出现:有时候,您需要等待一个元素出现或变为可见状态后再与它进行交互。
您可以使用JavaScript等待元素出现或变为可见状态后再进行交互。
# 等待元素在页面上可见
element = driver.find_element(By.CSS_SELECTOR,'#my-element')
driver.execute_script("""
    var wait = setInterval(function() {
        if (arguments[0].offsetParent !== null) {
            clearInterval(wait);
            // 元素现在可见,可以对其进行操作
        }
    }, 100);
""", element)

4 执行自定义JavaScript:使用execute_script方法可以执行您编写的任何自定义 JavaScript 代码,
以完成测试或自动化任务。
driver.execute_script("console.log('Hello, world!');")

5 打开多窗口 
driver.execute_script("window.open('https://www.douban.com')")

** 这一块的只是示例 不用同学们进行记忆 但是我们可以积累 **

Selenium高级语法

  • page_source (elements源代码)

  • find() (在网页源码中寻找某个字符串是否存在)

  • find_element(By.LINK_TEXT) (根据链接文本获取 一般处理翻页)

  • node.get_attribute (node 代表的是节点名 get_attribute代表的是获取属性名)

  • node.text() (获取节点的文本内容 包含子节点和后代节点)

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

# 加载驱动
driver = webdriver.Chrome()

# 访问百度
# driver.get('https://www.baidu.com/')

""" 
1拿到百度的数据结构源码 page_source  
这个指的不是网页源代码而是我们前端页面最终渲染的结果也就是我们element中的数据
"""
# html = driver.page_source
# print(html)

"""
2 find() 在html源码中查找某个字符是否存在
如果存在则会返回一段数字  如果不存在 不会报错 但是会返回-1
find应用场景 比如翻页爬取 
"""
# print(html.find("kw"))
# print(html.find("kwwwwwwwwwwwwwwwwwww"))

""" 3 find_element_by_link_text("链接文本") 
# driver.get('https://www.gushiwen.cn/')
# time.sleep(3)
# # 根据链接文本内容定位按钮
# driver.find_element(By.LINK_TEXT,'下一页').click()  # 点击豆瓣第一页的下一页
# # 画面会跳转到第二页 打印的是第二页的源码
# time.sleep(3)
# print(driver.page_source)

"""4 node.get_attribute("属性名")  node代表的是你想获取的节点 """

# url = 'https://movie.douban.com/top250'
# driver.get(url)
# a_tag = driver.find_element(By.XPATH,'//div[@class="item"]/div[@class="pic"]/a')
# print(a_tag.get_attribute('href'))

""" 5 node.text 获取节点的文本内容 包含子节点和后代节点 """
# driver.get('https://movie.douban.com/top250')
# time.sleep(2)
# div_tag = driver.find_element(By.XPATH,'//div[@class="hd"]')
# print(div_tag.text)

Selenium设置无界面模式

绝大多数服务器是没有界面的,selenium控制谷歌浏览器也是存在无界面模式的(又称之为无头模式) 开启无界面模式的方法

  • 实例化配置对象

options = webdriver.ChromeOptions()

  • 配置对象添加开启无界面模式的命令

options.add_argument("--headless")

  • 配置对象添加禁用gpu的命令

options.add_argument("--disable-gpu")

  • 实例化带有配置对象的driver对象

driver = webdriver.Chrome(chrome_options=options)

from selenium import webdriver

# 创建一个配置对象
options = webdriver.ChromeOptions()
# 开启无界面模式
options.add_argument('--headless')
# 实例化带有配置的driver对象
driver = webdriver.Chrome(options=options)

driver.get('http://www.baidu.com/')
html = driver.page_source
print(html)
driver.quit()

Selenium被识别问题解决方案

selenium做爬虫能解决很多反爬问题,但是selenium也有很多特征可以被识别,比如用selenium驱动浏览器后window.navigator.webdriver值是true,而正常运行浏览器该值是未定义的(undefined)

 

import time

from selenium import webdriver

# 使用chrome开发者模式
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])

# 禁用启用Blink运行时的功能
options.add_argument("--disable-blink-features=AutomationControlled")

# Selenium执行cdp命令  再次覆盖window.navigator.webdriver的值
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
                    Object.defineProperty(navigator, 'webdriver', {
                      get: () => undefined
                    })
                  """
})


driver.get('https://www.baidu.com/')

time.sleep(3)

Selenium综合案例之当当网书籍信息爬取

import csv
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
"""
爬取当当网python爬虫书籍信息并保存到csv文件中 
"""

class DDspider:
    # 初始化方法
    def __init__(self):
        # 加载驱动
        self.driver = webdriver.Chrome()

        # 发起请求
        self.driver.get('http://www.dangdang.com/')

        # 窗口最大化
        # self.driver.maximize_window()

        # 定位输入框
        ipt_tag = self.driver.find_element(By.ID, 'key_S')
        ipt_tag.send_keys('python爬虫')
        time.sleep(1)

        # 定位搜索框
        serach_ipt = self.driver.find_element(By.CLASS_NAME, 'button')
        serach_ipt.click()
        time.sleep(1)

    # 解析目标数据
    def Getitem(self):
        # 将滚轮拉到底部为的是让全部的source进行加载完全
        """想办法把滚轮拖动到最后"""
        # window.scrollTo 拖动滚轮 第一个参数0 表示从起始位置开始拉 第二个参数表示的是整个窗口的高度
        self.driver.execute_script(
            'window.scrollTo(0,document.body.scrollHeight)'  # 这一点属于js代码 不需要死记 但是需要积累
        )
        time.sleep(1)

        lilist = self.driver.find_elements(By.XPATH, '//ul[@id="component_59"]/li')
        print(len(lilist))

        # 定义列表用于存放一页中所有书的信息
        books = []
        for i, item in enumerate(lilist):
            try:
                # 定义字典用于存放每一本书的信息
                book = {}
                # 书图
                if i == 0:
                    book['img'] = item.find_element(By.XPATH, './a/img').get_attribute('src')
                else:
                    book['img'] = 'https:' + item.find_element(By.XPATH, './a/img').get_attribute('data-original')

                # 书名
                book['name'] = item.find_element(By.XPATH, './p[@class="name"]/a').get_attribute('title')

                # 价格
                book['price'] = item.find_element(By.XPATH, './p[@class="price"]/span').text

                # 作者
                book['author'] = item.find_element(By.XPATH, './p[@class="search_book_author"]/span[1]').text

                # 出版时间
                book['Publication_time'] = item.find_element(By.XPATH, './/p[@class="search_book_author"]/span[2]').text

                # 出版社
                book['Publishing_house'] = item.find_element(By.XPATH, './/p[@class="search_book_author"]/span[3]').text

                books.append(book)
            except Exception as e:
                print(e.__class__.__name__)

        # print(books,len(books))
        return books

    # 翻页函数
    def Next_page(self):
        alldata = []
        while True:
            books = self.Getitem()
            alldata += books
            print(len(alldata),"*" * 50)
            if self.driver.page_source.find("next none") == -1:
                next_tag = self.driver.find_element(By.XPATH, '//li[@class="next"]/a')
                self.driver.execute_script("arguments[0].click();", next_tag)
                time.sleep(1)
            else:
                self.driver.quit()
                break
        return alldata

    # 写入数据
    def WriteData(self,alldata):
        headers = ('img', 'name', 'price', 'author','Publication_time','Publishing_house')
        with open('当当.csv', mode='w', encoding='utf-8', newline="")as f:
            writer = csv.DictWriter(f, headers)
            writer.writeheader()  # 写入表头
            writer.writerows(alldata)

if __name__ == '__main__':
    DD = DDspider()
    alldata = DD.Next_page()
    DD.WriteData(alldata)
 

这篇关于爬虫学习--18.反爬斗争 selenium(3)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1020764

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件