python Web抓取(二)selenium模块的使用、对浏览器的按键操作及错误处理
建议以下帖子:
教你在Windows上搭建Python+Selenium环境:https://blog.csdn.net/huilan_same/article/details/52888262
python webdriver 的异常:https://blog.csdn.net/huilan_same/article/details/52815047
Selenium库的使用:https://blog.csdn.net/weixin_36279318/article/details/79475388
以下是我满怀信心学习却被异常为所欲为的调戏但是坚持抵抗留下的充满逻辑的笔记
一、用selenium模块控制浏览器
安装selenium 3.1410
selenium能让用户通过Python直接控制浏览器,实际点击链接,填写登录信息,几乎就像一个人类与浏览器交互。这能比使用 Request 和 Beautiful Soup 模块完成更多的事情,能让你以更高级的方式和浏览器交互,但是也有一个确定,比如当你只是想下载一个文件时,前者就有些复杂,并且难以在后台运行
安装针对chrome的浏览器驱动(注意版本):http://selenium-release.storage.googleapis.com/index.html
1.1启动selenium控制的浏览器
以 form selenium import webdriver 来导入webderiver模块
>>> from selenium import webdriver
>>> browser=webdriver.Chrome()
>>> browser.get('http://www.baidu.com')
>>> browser.quit()#退出
1.2在页面中寻找元素
Webdriver对象有好几种方法,用于在页面中寻找元素。他们被分成 find_element_* 和 find_elements_* 方法。前者返回的WebElement对象,代表页面中匹配查询的第一个元素,而后者包含所有匹配元素的列表。
在Webdriver对象上调用的方法:
方法名 | 返回的WebElement对象/列表 |
browser.find_element_by_class_name(name) browser.find_elements_by_class_name(name) |
类名为name的元素 |
browser.find_element_by_css_selector(selector) browser.find_elements_by_css_selector(selector) |
selector为css选择器,如同我们写样式时写的内容如“#head” 返回匹配的元素 |
browser.find_element_by_id(id) browser.find_elements_by_id(id) |
id名为id的元素 |
browser.find_element_by_link_text(text) browser.find_elements_by_link_text(text) |
返回a元素中文本内容完全为text的a元素 |
browser.find_element_by_partial_link_text(text) browser.find_elements_by_partial_link_text(text) |
partial:局部 返回a元素中文本内容包含text的元素 |
browser.find_element_by_name(name) browser.find_elements_by_name(name) |
匹配name属性值为name的元素 |
browser.find_element_by_tag_name(name) |
匹配标签名为name的元素 (大小写无关‘a’和'A'都会匹配便签<a>) |
注意:
除了最后一个方法,其他的参数都是区分大小写的。如果页面上没有元素被匹配,selenium模块就会抛出 NoSuchElement 异常。即要配合 try....except 语句
使用类名和id来查找元素时,注意不要有空格,因为空格前后的内容会被HTML解释成两个
当界面跳转后,如果原来的查找结果还能有匹配,那么就不用重新匹配
上述方法假如匹配成功,会返回一个 WebElement 对象,对于这个对象可以使用下面的属性或方法:
方法或者属性 | 描述 |
tag_name | 标签名,例如‘a’(这个是返回的值)代表<a>元素 |
get_attribute(name) | 该元素 name属性 的值 |
text | 该元素内的文本,例如<span>hello</span>中的‘hello’ |
clear() |
对于文本字段或文本区域元素,清除其中输入的文本 不能清除<a>里面的,估计<span>里的也不能 |
is_displayed() | 如果该元素可见,返回True,可以用于先判断元素是否可见 |
is_enabled() | 对于输入元素,如果该元素启用,返回True |
is_selected() | 对于复选框或者单选元素,如果该元素被选中,返回True |
location | 一个字典,包含键‘x’和'y',表示该元素在页面上的位置 |
示例:
from selenium import webdriver
browser=webdriver.Chrome()
browser.get('http://www.baidu.com')
try:
elem=browser.find_element_by_class_name('head_wrapper')#寻找第一个类名为head_wrapper的元素
print('找到了相应类名的元素:<%s>'%(elem.location))
except:
print('没有找到这个元素。')
browser.quit()
1.3点击页面
利用 WebElement 对象的click()方法,我们可以模拟鼠标在该元素上单击。效果与我们手动单击的效果一样
示例:
from selenium import webdriver
browser=webdriver.Chrome()
browser.get('http://www.baidu.com')
try:
elem=browser.find_element_by_class_name('mnav')#会匹配到“新闻”
print('找到了相应类名的元素:<%s>'%(elem.location))
elem.click()
except:
print('没有找到这个元素。')
browser.quit()
1.4输入内容send_key()
是webElement对象的方法
1.5填写并提交表单
webElement对象方法 submit() ,在任何元素上使用 submit() 方法,都相当于点击该元素所在表单的submit按钮
示例:
import logging #此行以及下两行行是使用日志内容
logging.basicConfig(level=logging.CRITICAL,format=' %(asctime)s - %(levelname)s -%(message)s')
from selenium import webdriver
logging.disable(logging.ERROR)
browser=webdriver.Chrome()
browser.get('http://www.baidu.com')
try:
elem=browser.find_element_by_id('kw')
logging.critical('输入框已经找到')
elem.send_keys('长泽雅美') #是keys
logging.critical('内容已输入')
searchElem=browser.find_element_by_id('su')
logging.critical('按钮已经找到')
searchElem.submit()
logging.critical('已提交')
except:
print('没有找到这个元素。')
browser.quit()
注意,不用在寻找提交按钮上花费太长时间,因为在任何元素上使用 submit() 方法,都等同于你点击了这个元素所属表单的提交按钮,你甚至可以这样(我不确定,你可以打开百度首页,输入内容演示一下,就能知道我的意思了你可能发现你不需要点击搜索按钮,就会出现搜索结果)
---snip----
elem.submit() #改动在这里
logging.critical('已提交')
---snip---
1.6发送特殊键
当我们需要向浏览器击键行为,如按下‘F12’,这时仅通过字符串值输入时不可能完成的,selenium为我们这种需要提供了一个解决办法:这些值保存在selenium.webdriver.common.keys模块的属性中。由于这个模块的名字非常长,我们可以通过from selenium.webdriver.common.keys import Keys,让from selenium.webdriver.common.keys.Keys.F12简写为:Keys.F12
下表展示了一些selenium.webdriver.common.keys模块中常用的变量:
属性 | 含义 |
Keys.DOWN,Keys.UP,Keys.LEFT,Keys.RIGHT | 键盘方向键 |
Keys.ENTER,Keys.RETURN | 回车键和换行键 |
Keys.HOME,Keys.END,Keys.PAGE_DOWN,Keys.PAGE_UP | |
Keys.ESCAPE,Keys.BACK_SPACE,Keys.DELETE | Esc,backspace和消除键 |
Keys.F1,Keys.F2........Keys.F12 | |
Keys.TAB |
示例:使页面向下滚动一次
import time
import logging #此行以及下两行行是使用日志内容
logging.basicConfig(level=logging.CRITICAL,format=' %(asctime)s - %(levelname)s -%(message)s')
from selenium import webdriver
logging.disable(logging.ERROR)
from selenium.webdriver.common.keys import Keys browser=webdriver.Chrome()
browser.get('http://www.baidu.com')
try:
elem=browser.find_element_by_id('kw')
logging.critical('输入框已经找到')
elem.send_keys('长泽雅美') #是keys
logging.critical('内容已输入')
searchElem=browser.find_element_by_id('su')
logging.critical('按钮已经找到')
elem.submit()
logging.critical('已提交')
htmlElem=browser.find_element_by_tag_name('html')
htmlElem.send_keys(Keys.PAGE_DOWN)
except:
print('没有找到这个元素。')
time.sleep(3) #不加这个暂停看不出来效果
browser.quit()
注意:
(未证明)要对合适的元素对象使用相应的按键,如果上面你对'elem'使用这不会有效果
是keys要加s
问题:
使用Keys.PAGE_DOWN,时必须在前面加sleep()才能实现
import time
import logging #此行以及下两行行是使用日志内容
logging.basicConfig(level=logging.CRITICAL,format=' %(asctime)s - %(levelname)s -%(message)s')
from selenium import webdriver
logging.disable(logging.ERROR)
from selenium.webdriver.common.keys import Keys browser=webdriver.Chrome()
browser.maximize_window()
browser.get('http://www.baidu.com')
try:
elem=browser.find_element_by_id('kw')
logging.critical('输入框已经找到')
elem.send_keys('长泽雅美') #是keys
logging.critical('内容已输入')
searchElem=browser.find_element_by_id('su')
logging.critical('按钮已经找到')
elem.submit()
logging.critical('已提交')
htmlElem=browser.find_element_by_tag_name('html')
logging.critical('html标签已找到')
time.sleep(2)
elem.send_keys(Keys.PAGE_DOWN)#必须前面使用sleep()暂停才有用
logging.critical('按键已激发') except:
print('没有找到这个元素。')
time.sleep(10)
browser.quit()
不能发送F5按键使浏览器窗口刷新(可以使用browser.refresh()),无论是对html标签元素还是其他元素使用均无效
import time
import logging #此行以及下两行行是使用日志内容
logging.basicConfig(level=logging.CRITICAL,format=' %(asctime)s - %(levelname)s -%(message)s')
from selenium import webdriver
logging.disable(logging.ERROR)
from selenium.webdriver.common.keys import Keys browser=webdriver.Chrome()
browser.maximize_window()
browser.get('http://www.baidu.com')
try:
elem=browser.find_element_by_id('kw')
logging.critical('输入框已经找到')
elem.send_keys('长泽雅美') #是keys
logging.critical('内容已输入')
searchElem=browser.find_element_by_id('su')
logging.critical('按钮已经找到')
elem.submit()
logging.critical('已提交')
htmlElem=browser.find_element_by_tag_name('html')
logging.critical('html标签已找到')
time.sleep(2)
elem.send_keys(Keys.F5)#必须前面使用sleep()暂停才有用
logging.critical('按键已激发') except:
print('没有找到这个元素。')
time.sleep(10)
browser.quit()
1.6点击浏览器按钮
这里的浏览器按钮指的是浏览器应用里的按钮,
browser.back() 点击返回按钮
browser.froward() 点击前进按钮
browser.refresh() 点击刷新按钮
browser.quit() 点击关闭窗口按钮
二、selenium的更多信息
browser.maximize_windows():设置浏览器大小为全屏
browser.set_window_size(500,500):设置浏览器窗口大小为500*500
组合键操作:https://www.cnblogs.com/mengyu/p/6942584.html
更详细的信息包括 拖放:https://www.cnblogs.com/zhongyehai/p/9163740.html
说send_keys()不能输入中文的解决办法是send_keys(u' ')
三、遇到的问题:
1)selenium.common.exceptions.WebDriverException:Message: 'geckodriver' executable needs to be in PATH.
问题是有你没有浏览器驱动,或者浏览器驱动所在的文件夹没有在环境变量PATH里面
在执行以下代码时出现了上个异常
>>> from selenium import webdriver
>>> browser=webdriver.Firefox()
Traceback (most recent call last):
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\common\service.py", line 76, in start
stdin=PIPE)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 775, in __init__
restore_signals, start_new_session)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 1178, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] 系统找不到指定的文件。 During handling of the above exception, another exception occurred: Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
browser=webdriver.Firefox()
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\firefox\webdriver.py", line 164, in __init__
self.service.start()
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\common\service.py", line 83, in start
os.path.basename(self.path), self.start_error_message)
selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable needs to be in PATH.
解决办法:(错误虽然没有别我解决,但基于相似问题有庞大的搜索结果。相信仍然有一定的借鉴意义)
错误是英文的,我先把他翻译过来之后,这个错误的意思是“geckodriver”需要在环境变量访问到才能执行。 由于是第一次使用selenium模块,我搜索了模块的使用方法,然后发现需要针对Firefox浏览器的webdriver驱动文件,然后就下载了。发现下载太慢,然后又按照另外一个方法解决办法:“出现这样的错误是浏览器没有安装到默认位置,需要修改selenium模块里的两个参数”(这个办法没有用,你只需要将浏览器的安装文件夹添加到PATH里面)
D:\Programs\Python\Python35-32\Lib\site-packages\selenium-3.0.1-py3.5.egg\selenium\webdriver\firefox的 webdriver.py文件中修改为 def_init_(self,firefox_profile=None,firefox_binary=FirefoxBinary("D:/Program Files (x86)/Mozilla Firefox/firefox.exe")#其中的是浏览器的安装位置 Firefox_binary.py文件中修改为 def_init_(self,firefox_path="D:/Program Files (x86)/Mozilla Firefox/firefox.exe",log_file=None);
然后发现还是报同样的错误,这是下载驱动文件也好了,网上说要需要配置Path变量的,我直接把它放在Python的根目录下了,因为这里已经配置过了
geckodriver的网盘链接: https://pan.baidu.com/s/1fWLiTd_1p3vn9CzBTJcfpg 提取码: uki4
GitHub链接:https://github.com/mozilla/geckodriver/releases
然后程序能运行了,能打开一个火狐浏览器窗口
>>> from selenium import webdriver
>>> browser=webdriver.firefox()
我没高兴太长时间,准确来说,上述成功只运行了一次,就不行了。我试了很多办法,然后放弃了,选择了chrome
我试了下载高版本的selenium,但pip中自动安装的最新版本是3.141,我上网找了selenium的版本:版本在这里,不知道那个才是python要的,放弃
以上办法来源于参考经验:
https://www.cnblogs.com/fangfangs/p/f0000000f.html
问题 selenium.common.exceptions.SessionNotCreatedException: Message: Unable to find a matching set of capabilities
这个问题是由于你的浏览器驱动文件(geckodriver、chromedriver)版本和selenium版本不兼容导致的
>>> from selenium import webdriver
>>> browser=webdriver.firefox()
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
browser=webdriver.Firefox()
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\firefox\webdriver.py", line 174, in __init__
keep_alive=True)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
self.start_session(capabilities, browser_profile)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 252, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException: Message: Unable to find a matching set of capabilities
上网搜索发现是浏览器版本问题,决定更新浏览器版本再说,之后发现这个方法没用
首先应该让浏览器、浏览器驱动、selenium、三个的版本互相兼容:他们之间版本关系我在网上没有找到整理的好的。我就在geckodriver(针对火狐的浏览器驱动)的主页上看介绍,发现我下的v24,竟然要求Firefox是66版本的,而浏览器提示我65已经是最新,没有办法我只能继续看下去,然后找到了一个
通过查看C:\Users\Administrator.SC-2016\AppData\Local\Programs\Python\Python37\Lib\site-packages\selenium\webdriver\firefox\webdriver.xpi\install.rdf文件来查看你安装的selenium支持的浏览器版本(通过winrar查看这个文件),发现我的支持Firefox版本是3.0到52的:
然后发现Firefox版本还是太高,我下了一个51.***的。
启发:
不要想着征服错误,特别是在还有别的替代方法的情况下。
不要被搜索出来的解决办法的困难度吓到,要尽量找到高质量的解决办法,像有些错误,压根就是没按照正常流程去做而出错的。如果你找到的解决办法没有把这个讲明白,会很浪费时间
python Web抓取(二)selenium模块的使用、对浏览器的按键操作及错误处理的更多相关文章
- python Web抓取(一)[没写完]
需要的模块: python web抓取通过: webbrowser:是python自带的,打开浏览器获取指定页面 requests:从因特网上下载文件和网页 Beautiful Soup:解析HTML ...
- 《编程快速上手》--web抓取--利用webbrowser模块的mapIT.py
1.代码如下 #! python3 # mapIT.py - Launches a map in the browser using an address from the # command lin ...
- Python股票信息抓取(二)
在一的基础上,想着把所有的折线图放在一个图中,然后图的结果如图所示: 不是略丑,是很丑~ 依然的单进程,只是将图标结果放在了一张图里 代码如下: #-*-coding:utf-8 -*- import ...
- python数据抓取分析(python + mongodb)
分享点干货!!! Python数据抓取分析 编程模块:requests,lxml,pymongo,time,BeautifulSoup 首先获取所有产品的分类网址: def step(): try: ...
- python自动化之web抓取
''' 从web抓取数据: webbrowser:是python自带的,打开浏览器获取指定页面. requests:从因特网上下载文件和网页. Beautiful Soup:解析HTML,即网页编写的 ...
- 如何用 Python 实现 Web 抓取?
[编者按]本文作者为 Blog Bowl 联合创始人 Shaumik Daityari,主要介绍 Web 抓取技术的基本实现原理和方法.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正 ...
- python requests抓取NBA球员数据,pandas进行数据分析,echarts进行可视化 (前言)
python requests抓取NBA球员数据,pandas进行数据分析,echarts进行可视化 (前言) 感觉要总结总结了,希望这次能写个系列文章分享分享心得,和大神们交流交流,提升提升. 因为 ...
- Python爬虫抓取东方财富网股票数据并实现MySQL数据库存储
Python爬虫可以说是好玩又好用了.现想利用Python爬取网页股票数据保存到本地csv数据文件中,同时想把股票数据保存到MySQL数据库中.需求有了,剩下的就是实现了. 在开始之前,保证已经安装好 ...
- Python数据抓取技术与实战 pdf
Python数据抓取技术与实战 目录 D11章Python基础1.1Python安装1.2安装pip1.3如何查看帮助1.4D1一个实例1.5文件操作1.6循环1.7异常1.8元组1.9列表1.10字 ...
随机推荐
- Servlet基础(一)
JavaEE:企业级开发技术 <一.基础概念>j2ee:jdk1.1--1.4 ----->> j2ee1.1 1.2 javaee:jdk--5,6,7 ...
- Android TextView加上阴影效果
<TextView android:id="@+id/test_shadow" android:layout_width="wrap_content" a ...
- POJ 2029 Get Many Persimmon Trees 【 二维树状数组 】
题意:给出一个h*w的矩形,再给出n个坐标,在这n个坐标种树,再给出一个s*t大小的矩形,问在这个s*t的矩形里面最多能够得到多少棵树 二维的树状数组,求最多能够得到的树的时候,因为h,w都不超过50 ...
- 我所认识的EXT2(一)
前言: 本文是笔者自己在学习文件系统中的一些体会,写出来和大家分享一下.本文首先是介绍了下文件系统的一些理论概念,然后分析了ext2文件系统的原理和部分源码. 文件系统是什么: 人们在认识一件陌生事物 ...
- win10 无法访问XP 共享目录原因
win10 无法访问XP 共享目录原因 *现象: 在地址栏中输入\\192.168.100.5 (XP文件服务器),出现:.....找不到网络路径, 此连接尚未还原. ...
- confluence6.0.3安装文档
一.Atlassian Confluence 6.0.3安装文档包含内容 1.wiki的安装步骤: 2.旧系统迁移中碰到的无法编辑和问题和解决方案: 3.wiki源码安装包.连接mysql用的jar包 ...
- vb常用的内部函数(二):字符串函数
len(string):计算字符串长度函数.返回字符串string中字符的个数.一个汉字为一个字符,空格也为一个字符,空字符串的长度为0. Ltrim(string).Rtrim(string).Tr ...
- java 截取点后面的字符串
int index = path.lastIndexOf("."); char[] ch = path.toCharArray(); //根据 copyValueOf(char[] ...
- vue中的methods、computed和watch
1.computed属性: 经过处理返回的数据值,只要源数据没有发生改变,computed函数里面对相应的数据就不会反生改变,相当于缓存在本地;发生改变的时候,computed对应数据的函数才会发生改 ...
- 错误解决:error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
今天看到一个比较有趣的题目,如下代码,分析输出结果 #include <stdio.h> void num(int &b) { b = 222; return; } int mai ...