基于Python +Selenium的爬虫详解

news2024/10/7 12:29:16

今天我们来详细学习一些 selenium 的强大用法

一、selenium简介

由于requests模块是一个不完全模拟浏览器行为的模块,只能爬取到网页的HTML文档信息,无法解析和执行CSS、JavaScript代码,因此需要我们做人为判断;

1、什么是selenium

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法执行javaScript代码的问题。
selenium模块本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器;由于selenium解析执行了CSS、JavaScript所以相对requests它的性能是低下的;

2、selenium的用途

1)selenium可以驱动浏览器自动执行自定义好的逻辑代码,也就是可以通过代码完全模拟成人类使用浏览器自动访问目标站点并操作,那我们也可以拿它来做爬虫。
2)selenium本质上是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等…进而拿到网页渲染之后的结果,可支持多种浏览器

二、selenium的安装与测试

1、下载selenium模块:

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium
或者在pycharm中下载

2、安装浏览器驱动

  1. Google浏览器驱动(在下载驱动之前,查看一下chrome浏览器的版本号,如下:

国内镜像网站地址:http://npm.taobao.org/mirrors/chromedrive


当然也可以去官网找最新的版本,官网: https://sites.google.com/a/chromium.org/chromedriver/downloads

另外注意:把下载好的chromedriver.exe放到python安装路径的scripts目录中即可

  1. firefox浏览器驱动

selenium3默认支持的webdriver是Firfox,而Firefox需要安装geckodriver

下载链接:https://github.com/mozilla/geckodriver/releases

  1. 测试是否安装成功

import time
from selenium import webdriver
browser=webdriver.Chrome() 
#实例化1个谷歌浏览器对象
browser.get('https://www.baidu.com/')  
time.sleep(5)
browser.close()

三、selenium的使用

所谓模拟浏览器基本就是下面的流程:

1.请求

2.显示页面

3.查找元素

4.点击可点击元素

所以如何使用selenium找到页面中的标签,进而触发标签事件,就会变的尤为重要

1. selenium选择器

要想定位页面的元素,selenium也提供了一系列的方法。

  1. 通过标签id属性进行定位

browser.find_element_by_id('kw') # 其中kw便是页面中某个元素的id值
  1. 通过标签name属性进行定位

# 两种方式是一样的
browser.find_element_by_name("wd") # 其中wd是页面中某个元素的name值
  1. 通过标签名进行定位
browser.find_element_by_tag_name("img") # img参数表示的就是图片标签img
  1. 通过CSS查找方式进行定位
browser.find_elements_by_css_selector("#kw") # 根据选择器进行定位查找,其中#kw表示的是id选择器名称是kw的
  1. 通过xpath方式定位

browser.find_element_by_xpath('//*[@id="kw"]') # 参数即是xpath的语法
  1. 通过搜索页面中链接进行定位

有时候不是一个输入框也不是一个按钮,而是一个文字链接,我们可以通过link


browser.find_element_by_link_text("设置")

通过搜索页面中链接进行定位 ,可以支持模糊匹配**

browser.find_element_by_partial_link_text("百度") # 查找页面所有的含有百度的文字链接

2. selenium显示等待和隐式等待

显示等待:就是明确要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,就会跳出异常Exception

操作格式:WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

WebDriverWait()一般由until()或 until_not()方法配合使用 until(method, message=’ ‘):调用该方法提供的驱动程序作为一个参数,直到返回值为True until_not(method, message=’ '):调用该方法提供的驱动程序作为一个参数,直到返回值为False


from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.chrome()
driver.get('http://www.baidu.com')

element = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, "kw")))
element.send_keys('selenium')

隐式等待:就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。

注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部断的刷新页面去寻找我们需要的元素


driver.implicitly_wait() 默认设置为0

例如:driver.implicitly_wait(10) 。如果元素在10s内定位到了,继续执行。如果定位不到,将以循环方式判断元素是否被定位到。如果在10s内没有定位到,则抛出异常

from selenium import webdriver

driver = webdriver.chrome()
driver.get('http://www.baidu.com')
# 隐式等待10秒
driver.implicitly_wait(10)

另外还有一种就是我们常用的sleep,我们称为:强制等待。有时候我们希望脚本在执行到某一位置时暂停一段时间等待页面加载,这时可以使用sleep()方法。sleep()方法会固定休眠一定的时长,然后再继续执行。sleep()方法默认参数以秒为单位。

from time import sleep
from selenium import webdriver

driver = webdriver.chrome()
driver.get('http://www.baidu.com')
# 强制休眠2秒
sleep(2)
driver.find_element_by_id("kw").send_keys("selenium")

3. 元素交互操作

用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击、双击、点击鼠标右键、拖拽(滑动验证)等等。而selenium给我们提供了一个类来处理这类事件——ActionChains;


selenium.webdriver.common.action_chains.ActionChains(driver)

这个类基本能够满足我们所有对鼠标操作的需求。

  1. actionChains的基本使用

首先需要了解ActionChains的执行原理,当你调用ActionChains的方法时,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法时,队列中的时间会依次执行。

这种情况下我们可以有两种调用方法:

链式写法


menu = driver.find_element_by_css_selector(".div1")
hidden_submenu =    driver.find_element_by_css_selector(".div1 #menu1")
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()

分步写法


menu = driver.find_element_by_css_selector(".div1")
hidden_submenu = driver.find_element_by_css_selector(".div1 #menu1")

actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()

两种写法本质是一样的,ActionChains都会按照顺序执行所有的操作。

  1. actionChains方法列表

click(on_element=None) ——单击鼠标左键
click_and_hold(on_element=None) ——点击鼠标左键,不松开
context_click(on_element=None) ——点击鼠标右键
double_click(on_element=None) ——双击鼠标左键
drag_and_drop(source, target) ——拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开
key_down(value, element=None) ——按下某个键盘上的键
key_up(value, element=None) ——松开某个键
move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标
move_to_element(to_element) ——鼠标移动到某个元素
move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置
perform() ——执行链中的所有动作
release(on_element=None) ——在某个元素位置松开鼠标左键
send_keys(*keys_to_send) ——发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素

示例代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

try:
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    # 1、往jd发送请求
    driver.get('https://www.jd.com/')
    # 找到输入框输入围城
    input_tag = driver.find_element_by_id('key')
    input_tag.send_keys('华为')
    # 键盘回车
    input_tag.send_keys(Keys.ENTER)
    time.sleep(2)
    # 找到输入框输入墨菲定
    input_tag = driver.find_element_by_id('key')
    input_tag.clear()
    input_tag.send_keys('樊登读书')
    # 找到搜索按钮点击搜索
    button = driver.find_element_by_class_name('button')
    button.click()
    time.sleep(10)

finally:
    driver.close()

或者前进后退相关


import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.cnblogs.com/xuanyuan/')

browser.find_element_by_partial_link_text('我是如何把计算机网络考了100分的?').click()

time.sleep(3)
browser.back()  # 后退
time.sleep(3)
browser.forward()  # 前进
time.sleep(5)
browser.close()

四、综合案例


import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC  # available since 2.26.0
from selenium.webdriver.support.ui import WebDriverWait  # available since 2.4.0
from selenium.webdriver.support import expected_conditions

import pandas as pd


class MyCrawler(object):
    def __init__(self):
        self.path = "./data"

        if not os.path.exists(self.path):
            os.mkdir(self.path)

        self.driver = webdriver.Chrome()
        self.base_url = "http://data.house.163.com/bj/housing/trend/district/todayprice/{date:s}/{interval:s}/allDistrict/1.html?districtname={disname:s}#stoppoint"
        self.data = None

    def craw_page(self, date="2020.01.01-2020.12.30", interval="month", disname="全市"):
        driver = self.driver
        url = self.base_url.format(date=date, interval=interval, disname=disname)
        driver.get(url)
        try:
       
            WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "resultdiv_1")))
            self.data = pd.DataFrame()
            ct = True
            while ct:
                self.get_items_in_page(driver)
                e_pages = driver.find_elements_by_xpath(
                    '//div[@class="pager_box"]/a[@class="pager_b current"]/following::a[@class="pager_b "]')
                if len(e_pages) > 0:
                    next_page_num = e_pages[0].text
                    e_pages[0].click()

                    # 通过判断当前页是否为我们点击页面的方式来等待页面加载完成
                    WebDriverWait(driver, 10).until(
                        expected_conditions.text_to_be_present_in_element(
                            (By.XPATH, '//a[@class="pager_b current"]'),
                            next_page_num
                        )
                    )
                else:
                    ct = False
                    brea
            return self.data
        finally:
            driver.quit()
            
    def get_items_in_page(self, driver):
        e_tr = driver.find_elements_by_xpath("//tr[normalize-space(@class)='mBg1' or normalize-space(@class)='mBg2']")
        temp = pd.DataFrame(e_tr, columns=['web'])
        temp['时间'] = temp.web.apply(lambda x: x.find_element_by_class_name('wd2').text.split(' ')[0])
        temp['套数'] = temp.web.apply(lambda x: x.find_element_by_class_name('wd5').text)
        temp['均价'] = temp.web.apply(lambda x: x.find_element_by_class_name('wd7').text)
        temp['去化'] = temp.web.apply(lambda x: x.find_element_by_class_name('wd14').text)
        del temp['web']

        self.data = pd.concat([temp, self.data], axis=0)


mcraw = MyCrawler()
data = mcraw.craw_page()

data= data.sort_values(by='时间')
print(data.to_string(index=False))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1351925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OR-3H7(车规级),对标ACPL-217等

提供隔离反馈 逻辑电路之间的接口 提供1通道和4通道 电平转换 DC和AC输入 SMPS中的调节反馈电路 消除接地环路 特征 电流传输比 : IF 5mA时最小 50%,VCE 5V,Ta25 C 高输入输出隔离电压。(VISO3,750Vrms&…

微服务-理论(CAP,一致性协议)

CAP理论 关于CAP理论的介绍可以直接看这篇文章 CAP分别是什么? 一致性(Consistency 一致性包括强一致性,弱一致性,最终一致性。 一致性其实是指数据的一致性,为什么数据会不一致呢? 如上面这张图&…

循环购模式:重塑消费返利的新趋势

在当今的消费市场中,返利模式已不再是新鲜事。然而,循环购模式以其独特的“消费即分享,分享即赚钱”的核心理念,正在迅速成为消费者和商家共同关注的新焦点。这种模式的出现,不仅重新定义了消费与返利的关系&#xff0…

23款奔驰GLC260L升级香氛负离子 车载香薰

奔驰原厂香氛系统激活原车自带系统,将香气加藏储物盒中,通过系统调节与出风口相结合,再将香味传达至整个车厢,达到净化车厢空气的效果,让整个车厢更加绿色健康,清新淡雅。星骏汇小许Xjh15863 产品功能&…

Shopee买家通系统批量注册虾皮买家号更轻松

Shopee买家通系统是一款高效、方便的工具,为用户提供了全自动批量注册虾皮买家号的便捷体验。在使用该系统进行自动注册时,用户可以享受到一系列智能化的操作,从而省去了繁琐的步骤,让整个注册流程更加轻松愉快。 首先&#xff0c…

暂时性死区:JavaScript 中隐藏的陷阱

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

CRM系统如何实现市场销售管理?CRM系统有哪些营销功能

CRM管理系统中的营销管理模块,它的锋芒常被销售管理所掩盖,但对于企业的业务来说同样重要。营销部门虽然不像销售人员一样直接面对客户,却是挖掘线索、商机的重要角色。CRM在市场营销领域的关键功能包括:营销漏斗、客户细分、营销…

软性演员-评论家算法 SAC

软性演员-评论家算法 SAC 软性演员-评论家算法 SAC优势原理软性选择模型结构目标函数重参数化熵正则化代码实现 软性演员-评论家算法 SAC 优势原理 DDPG 的问题在于,训练不稳定、收敛差、依赖超参数、不适应复杂环境。 软性演员-评论家算法 SAC,更稳定…

【算法挨揍日记】day46——377. 组合总和 Ⅳ\、96. 不同的二叉搜索树

377. 组合总和 Ⅳ 377. 组合总和 Ⅳ 题目描述: 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 解题思路: 算法思路&a…

深度生成模型之图像翻译GAN ->(个人学习记录笔记)

文章目录 深度生成模型之图像翻译GAN图像翻译的应用1. 风格迁移2. 数据增强3. 经典图像任务4. 内容创作5. 人脸图像编辑6. 人体图像编辑 图像翻译模型1. 有监督图像翻译模型2. 无监督图像翻译模型3. 多域图像翻译模型 深度生成模型之图像翻译GAN 图像翻译的应用 1. 风格迁移 …

基于python的leetcode算法介绍之动态规划

文章目录 零 算法介绍一 例题介绍 使用最小花费爬楼梯问题分析 Leetcode例题与思路[118. 杨辉三角](https://leetcode.cn/problems/pascals-triangle/)解题思路题解 [53. 最大子数组和](https://leetcode.cn/problems/maximum-subarray/)解题思路题解 [96. 不同的二叉搜索树](h…

网络安全B模块(笔记详解)- 数字取证

数据分析数字取证-attack 1.使用Wireshark查看并分析Windows 7桌面下的attack.pcapng数据包文件,通过分析数据包attack.pcapng找出恶意用户的IP地址,并将恶意用户的IP地址作为Flag(形式:[IP地址])提交; 解析:http.request.method==POST ​ Flag:[172.16.1.102] 2.继续…

属龙人的性格命运怎么样呢?

​ 属龙人慷慨大方,为人友爱,人缘很好,才情十足,细腻的思维和独到的见解常常能打动别人的心弦,在社交场合游刃有余,且魅力独特,身边不乏追求者。属龙人感情细腻,浪漫多情&#xff0…

通过软盘拷贝文件 - 华为OD统一考试

OD统一考试(B卷) 分值: 200分 题解: Java / Python / C 题目描述 有一名科学家想要从一台古董电脑中拷贝文件到自己的电脑中加以研究但此电脑除了有一个3.5寸软盘驱动器以外,没有任何手段可以将文件持贝出来,而且只有一张软盘可以…

开源CalDAV和CardDav网页客户端InfCloud

本文应网友 畅天 的要求折腾。他遇到了跨域问题,所以老苏找了个二合一的镜像来规避。其中使用的 Baikal 和 InfCloud 都是最新的版本; 什么是 Baikal ? Baikal 是一个免费的开源自托管 CalDAV 和 CardDAV 服务器,适用于想要管理其…

普中STM32-PZ6806L开发板(HAL库函数实现-TIM5 设置 PWM input, 获取频率跟占空比)

简介 初始化 TIM5 为 PWM input CH1, 获取输入PWM的频率和占空比电路原理图 连线 将 PC7 与 PA0使用跳线进行连接 其他知识 APIs /* Blocking mode: Polling */ HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); // 堵塞捕获开…

微信好友添加频繁的原因

01 微信好友添加频繁的原因 1. 添加好友的频率太高:短时间内添加多个好友,系统会认为账号被盗,从而限制用户添加好友; 2. 频繁的发送好友请求:在短时间内连续发送好友请求,也会导致微信限制操作&#xff0…

2021-01-03 excel实现列递增,行保持不变

需求:excel文档数据操作的时候发现自动递增只能实现列不变行号递增 我这里里需要的是列递增行不变 解决方式:通过一些函数的组合使用 INDIRECT("驻场明细!"&CHAR(ROW()62)&ROW(驻场明细!A$28)) INDIRECT()函数的使用: INDI…

Android studio ViewPager2应用设计

一、ViewPager2应用场景: ViewPager2是一个功能强大的滑动容器,提供灵活的页面切换和布局定制功能,使得应用程序界面更加丰富和交互性强,主要应用于以下场景: 1)、实现引导页或欢迎页:ViewPag…

妙手ERP功能更新:优化各平台描述设置、Ozon去除会员价设置、对接速虎速运.......

为了给卖家朋友带来更好的使用体验,更高效地运营跨境店铺,妙手ERP在上周优化了以下多项功能。 01、产品模块优化 全平台 - 优化各平台认领配置中的描述设置:具体优化见各平台描述设置 - 采集亚马逊产品到公用采集箱时,简易描述默…