技术标签: 爬虫 python selenium selenium框架 案例
selenium本身是一个自动化测试工具。它可以让python代码调用浏览器。并获取到浏览器中加载的各种资源。 我们可以利用selenium提供的各项功能。 帮助我们完成数据的抓取。
掌握 selenium发送请求,加载网页的方法
掌握 selenium简单的元素定位的方法
掌握 selenium的基础属性和方法
掌握 selenium退出的方法
安装:pip install selenium
它与其他库不同的地方是他要启动你电脑上的浏览器, 这就需要一个驱动程序来辅助.
这里推荐用chrome浏览器
chrome驱动地址:http://chromedriver.storage.googleapis.com/index.html
根据你电脑的不同自行选择吧. win64选win32即可.
然后关键的来了. 把你下载的浏览器驱动放在python解释器所在的文件夹
Windwos: py -0p 查看Python路径
Mac: open + 路径
例如:open /usr/local/bin/
前期准备工作完毕. 上代码看看 感受一下selenium
from selenium.webdriver import Chrome # 导入谷歌浏览器的类
# 创建浏览器对象
web = Chrome() # 如果你的浏览器驱动放在了解释器文件夹
web.get("http://www.baidu.com") # 输入网址
print(web.title) # 打印title
运行一下你会发现神奇的事情发生了. 浏览器自动打开了. 并且输入了网址. 也能拿到网页上的title标题.
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")
# 搜索关键字 杜卡迪
driver.find_element(By.ID, "kw").send_keys("杜卡迪")
# 点击id为su的搜索按钮
driver.find_element(By.ID, "su").click()
driver.page_source # 获取页面内容
driver.get_cookies()
driver.current_url
driver.close() # 退出当前页面
driver.quit() # 退出浏览器
selenium的导包:from selenium import webdriver
selenium创建driver对象:webdriver.Chrome()
selenium请求数据:driver.get("http://www.baidu.com/")
selenium查看数据: driver.page_source
关闭浏览器: driver.quit()
根据id定位元素: driver.find_element_by_id("kw")/driver.find_element(By.ID, "kw")
操作点击事件: click()
给输入框赋值:send_keys()
掌握 selenium定位元素的方法
掌握 selenium从元素中获取文本和属性的方法
通过selenium的基本使用可以简单定位元素和获取对应的数据,接下来我们再来学习下 定位元素的其他方法
元素定位的两种写法:
直接调用型
el = driver.find_element_by_xxx(value)
# xxx是定位方式,后面我们会讲,value为该方式对应的值
使用By类型(需要导入By) 建议使用这种方式
# 直接掉用的方式会在底层翻译成这种方式
from selenium.webdriver.common.by import By
driver.find_element(By.xxx,value)
元素定位的两种方式:
精确定位一个元素,返回结果为一个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)
元素定位的八种方法:
以下方法在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
find_element
和find_elements
的区别
by_link_text
和by_partial_link_text
的区别: 全部文本和包含某个文本
使用: 以豆瓣为例
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.implicitly_wait(10) # 等待节点加载完成
driver.get("https://www.douban.com/search?q=%E6%9D%B0%E6%A3%AE%E6%96%AF%E5%9D%A6%E6%A3%AE")
time.sleep(2)
# 使用id的方式获取右上角的搜索框
# ret1 = driver.find_element(By.ID, 'inp-query')
# ret1 = driver.find_element(By.ID, 'inp-query').send_keys("杰森斯坦森")
# ret1 = driver.find_element_by_id("inp-query")
# print(ret1)
# 输出为:<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>
# 搜索输入框 使用find_elements进行获取
# ret2 = driver.find_elements(By.ID, "inp-query")
# ret2 = driver.find_elements_by_id("inp-query")
# print(ret2)
#输出为:[<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>]
# 搜索按钮 使用xpath进行获取
# ret3 = driver.find_elements(By.XPATH, '//*[@id="inp-query"]')
# ret3 = driver.find_elements_by_xpath("//*[@id="inp-query"]")
# print(len(ret3))
# print(ret3)
# 匹配图片标签
ret4 = driver.find_elements(By.TAG_NAME, 'img')
for url in ret4:
print(url.get_attribute('src'))
#ret4 = driver.find_elements_by_tag_name("img")
print(len(ret4))
ret5 = driver.find_elements(By.LINK_TEXT, "浏览发现")
# ret5 = driver.find_elements_by_link_text("浏览发现")
print(len(ret5))
print(ret5)
ret6 = driver.find_elements(By.PARTIAL_LINK_TEXT, "浏览发现")
# ret6 = driver.find_elements_by_partial_link_text("浏览发现")
print(len(ret6))
# 使用class名称查找
ret7 = driver.find_elements(By.CLASS_NAME, 'nbg')
print(ret7)
driver.close()
注意:
find_element与find_elements区别
只查找一个元素的时候:可以使用find_element(),find_elements() find_element()会返回一个WebElement节点对象,但是没找到会报错,而find_elements()不会,之后返回一个空列表
查找多个元素的时候:只能用find_elements(),返回一个列表,列表里的元素全是WebElement节点对象
找到都是节点(标签)
如果想要获取相关内容(只对find_element()有效,列表对象没有这个属性) 使用 .text
如果想要获取相关属性的值(如href对应的链接等,只对find_element()有效,列表对象没有这个属性):使用 .get_attribute("href")
find_element_by_xxx方法仅仅能够获取元素对象,接下来就可以对元素执行以下操作 从定位到的元素中提取数据的方法
从定位到的元素中获取数据
el.get_attribute(key) # 获取key属性名对应的属性值
el.text # 获取开闭标签之间的文本内容
对定位到的元素的操作
el.click() # 对元素执行点击操作
el.submit() # 对元素执行提交操作
el.clear() # 清空可输入元素中的数据
el.send_keys(data) # 向可输入元素输入数据
使用示例:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver =webdriver.Chrome()
driver.get("https://www.douban.com/")
# 打印页面内容 (获取到以后可以进行后续的xpath,bs4 或者存储等)
print(driver.page_source)
ret4 = driver.find_elements(By.TAG_NAME, "h1")
print(ret4[0].text)
#输出:豆瓣
ret5 = driver.find_elements(By.LINK_TEXT, "下载豆瓣 App")
print(ret5[0].get_attribute("href"))
#输出:https://www.douban.com/doubanapp/app?channel=nimingye
driver.close()
根据xpath定位元素:driver.find_elements(By.XPATH,"//*[@id='s']/h1/a")
根据class定位元素:driver.find_elements(By.CLASS_NAME, "box")
根据link_text定位元素:driver.find_elements(By.LINK_TEXT, "下载豆瓣 App")
根据tag_name定位元素:driver.find_elements(By.TAG_NAME, "h1")
获取元素文本内容:element.text
获取元素标签属性: element.get_attribute("href")
向输入框输入数据: element.send_keys(data)
掌握 selenium处理cookie等方法
掌握 selenium中switch的使用
掌握selenium中无头浏览器的设置
我们已经基本了解了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)
通过driver.get_cookies()
能够获取所有的cookie
获取cookie
dictCookies = driver.get_cookies()
设置cookie
driver.add_cookie(dictCookies)
删除cookue
#删除一条cookie
driver.delete_cookie("CookieName")
# 删除所有的cookie
driver.delete_all_cookies()
为什么需要等待 如果网站采用了动态html技术,那么页面上的部分元素出现时间便不能确定,这个时候就可以设置一个等待时间,强制等待指定时间,等待结束之后进行元素定位,如果还是无法定位到则报错
页面等待的三种方法
强制等待
import time
time.sleep(n) # 阻塞等待设定的秒数之后再继续往下执行
显式等待(自动化web测试使用,爬虫基本不用)
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 10,0.5).until( EC.presence_of_element_located((By.ID, "myDynamicElement"))
# 显式等待指定某个条件,然后设置最长等待时间10,在10秒内每隔0.5秒使用指定条件去定位元素,如果定位到元素则直接结束等待,如果在10秒结束之后仍未定位到元素则报错
隐式等待 隐式等待设置之后代码中的所有元素定位都会做隐式等待
driver.implicitly_wait(10) # 在指定的n秒内每隔一段时间尝试定位元素,如果n秒结束还未被定位出来则报错
注意:
Selenium显示等待和隐式等待的区别 1、selenium的显示等待 原理:显示等待,就是明确要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,就会跳出异常Exception
(简而言之,就是直到元素出现才去操作,如果超时则报异常)
2、selenium的隐式等待
原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。 注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部断的刷新页面去寻找我们需要的元素
也可以使用 window_handles 方法来获取每个窗口的操作对象。例如:
# 1. 获取当前所有的窗口
current_windows = driver.window_handles
# 2. 根据窗口索引进行切换
driver.switch_to.window(current_windows[1])
driver.switch_to.window(web.window_handles[-1]) # 跳转到最后一个窗口
driver.switch_to.window(current_windows[0]) # 回到第一个窗口
driver.switch_to.frame(name/el/id) 传入的参数可以使iframe对应的id值,也可以是用元素定位之后的元素对象
动手:qq邮箱
在使用selenium登录qq邮箱的过程中,我们会发现,无法在邮箱的登录input标签中输入内容,通过观察源码可以发现,form表单在一个frame中,所以需要切换到frame中
alert = driver.switch_to_alert()
driver.forward() # 前进
driver.back() # 后退
driver.refresh() # 刷新
driver.close() # 关闭当前窗口
driver.maximize_window() #最大化浏览器窗口
优点
selenium能够执行页面上的js,对于js渲染的数据和模拟登陆处理起来非常容易
使用难度简单
爬取速度慢,爬取频率更像人的行为,天生能够应对一些反爬措施
缺点
由于selenium操作浏览器,因此会将发送所有的请求,因此占用网络带宽
由于操作浏览器,因此占用的内存非常大(相比较之前的爬虫)
速度慢,对于效率要求高的话不建议使用
获取cookie: get_cookies()
删除cookie: delete_all_cookies()
切换窗口:switch_to.window()
切换iframe: switch_to.frame()
options = webdriver.ChromeOptions()
options.add_experimental_option("prefs", { \
"profile.default_content_setting_values.media_stream_mic": 1, # 麦克风 1:allow, 2:block
"profile.default_content_setting_values.media_stream_camera": 1, # 摄像头 1:allow, 2:block
"profile.default_content_setting_values.geolocation": 1, # 地理位置 1:allow, 2:block
"profile.default_content_setting_values.notifications": 1, # 通知 1:allow, 2:block
'download.default_directory': download_path # 下载路径
})
driver = webdriver.Chrome(chrome_options=options)
其他参数
options.add_argument(‘headless’) # 无头模式
options.add_argument(‘window-size={}x{}’.format(width, height)) # 直接配置大小和set_window_size一样
options.add_argument(‘disable-gpu’) # 禁用GPU加速
options.add_argument(‘proxy-server={}’.format(self.proxy_server)) # 配置代理
options.add_argument(’–no-sandbox’) # 沙盒模式运行
options.add_argument(’–disable-setuid-sandbox’) # 禁用沙盒
options.add_argument(’–disable-dev-shm-usage’) # 大量渲染时候写入/tmp而非/dev/shm
options.add_argument(’–user-data-dir={profile_path}’.format(profile_path)) # 用户数据存入指定文件
options.add_argument(‘no-default-browser-check) # 不做浏览器默认检查
options.add_argument(“–disable-popup-blocking”) # 允许弹窗
options.add_argument(“–disable-extensions”) # 禁用扩展
options.add_argument(“–ignore-certificate-errors”) # 忽略不信任证书
options.add_argument(“–no-first-run”) # 初始化时为空白页面
options.add_argument(’–start-maximized’) # 最大化启动
options.add_argument(’–disable-notifications’) # 禁用通知警告
options.add_argument(’–enable-automation’) # 通知(通知用户其浏览器正由自动化测试控制)
options.add_argument(’–disable-xss-auditor’) # 禁止xss防护
options.add_argument(’–disable-web-security’) # 关闭安全策略
options.add_argument(’–allow-running-insecure-content’) # 允许运行不安全的内容
options.add_argument(’–disable-webgl’) # 禁用webgl
options.add_argument(’–homedir={}’) # 指定主目录存放位置
options.add_argument(’–disk-cache-dir={临时文件目录}’) # 指定临时文件目录
options.add_argument(‘disable-cache’) # 禁用缓存
options.add_argument(‘excludeSwitches’, [‘enable-automation’]) # 开发者模式
options.add_argument(’–disable-infobars’) # 禁止策略化
options.add_argument(‘–incognito’) # 隐身模式(无痕模式)
options.add_argument(‘–disable-javascript’) # 禁用javascript
options.add_argument(‘–hide-scrollbars’) # 隐藏滚动条, 应对一些特殊页面
options.add_argument(‘blink-settings=imagesEnabled=false’) # 不加载图片, 提升速度
options.binary_location = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" # 手动指定使用的浏览器位置
options.add_argument(‘lang=en_US’) # 设置语言
prefs = {“”:“”}
prefs[“credentials_enable_service”] = False
prefs[“profile.password_manager_enabled”] = False
chrome_option_set.add_experimental_option(“prefs”, prefs) # 屏蔽’保存密码’提示框
更多flags参数请参考:[https://blog.alanwei.com/blog/2021/03/15/chrome-flags/]
其他配置方式
可以自己复制谷歌浏览器的配置文件夹修改,并在启动时指定使用的文件夹
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:\\Users\\username\\AppData\\Local\\Google\\Chrome\\User Data\\Default")
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://ceshiren.com")
首先用cmd从谷歌浏览器目录以指定端口启动浏览器:
chrome.exe --remote-debugging-port=12306
再在脚本中使用参数来获取连接,这样就可以一直使用命令行打开的谷歌浏览器进行操作
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_experimental_option("debuggerAddress", "127.0.0.1:12306")
driver = webdriver.Chrome(options=options)
上面的参数很多不是经常用到或者在selenium操作过程中使用,所以这里并没有验证,供大家参考。
文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大
文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码
文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版
文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗
文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程
文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0
文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader
文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型
文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写
文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录
文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点
文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文