建议以下帖子:

  教你在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模块的使用、对浏览器的按键操作及错误处理的更多相关文章

  1. python Web抓取(一)[没写完]

    需要的模块: python web抓取通过: webbrowser:是python自带的,打开浏览器获取指定页面 requests:从因特网上下载文件和网页 Beautiful Soup:解析HTML ...

  2. 《编程快速上手》--web抓取--利用webbrowser模块的mapIT.py

    1.代码如下 #! python3 # mapIT.py - Launches a map in the browser using an address from the # command lin ...

  3. Python股票信息抓取(二)

    在一的基础上,想着把所有的折线图放在一个图中,然后图的结果如图所示: 不是略丑,是很丑~ 依然的单进程,只是将图标结果放在了一张图里 代码如下: #-*-coding:utf-8 -*- import ...

  4. python数据抓取分析(python + mongodb)

    分享点干货!!! Python数据抓取分析 编程模块:requests,lxml,pymongo,time,BeautifulSoup 首先获取所有产品的分类网址: def step(): try: ...

  5. python自动化之web抓取

    ''' 从web抓取数据: webbrowser:是python自带的,打开浏览器获取指定页面. requests:从因特网上下载文件和网页. Beautiful Soup:解析HTML,即网页编写的 ...

  6. 如何用 Python 实现 Web 抓取?

    [编者按]本文作者为 Blog Bowl 联合创始人 Shaumik Daityari,主要介绍 Web 抓取技术的基本实现原理和方法.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正 ...

  7. python requests抓取NBA球员数据,pandas进行数据分析,echarts进行可视化 (前言)

    python requests抓取NBA球员数据,pandas进行数据分析,echarts进行可视化 (前言) 感觉要总结总结了,希望这次能写个系列文章分享分享心得,和大神们交流交流,提升提升. 因为 ...

  8. Python爬虫抓取东方财富网股票数据并实现MySQL数据库存储

    Python爬虫可以说是好玩又好用了.现想利用Python爬取网页股票数据保存到本地csv数据文件中,同时想把股票数据保存到MySQL数据库中.需求有了,剩下的就是实现了. 在开始之前,保证已经安装好 ...

  9. 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字 ...

随机推荐

  1. 10 quick tips for Redis

    Redis is hot in the tech community right now. It's come a long way from being a small personal proje ...

  2. 改变GridView中列的宽度

    <asp:TemplateField HeaderText="规格型号" HeaderStyle-Width="24%">

  3. ARC下dealloc过程及.cxx_destruct的探究

    我是前言 这次探索源自于自己一直以来对ARC的一个疑问,在MRC时代,经常写下面的代码: - (void)dealloc { self.array = nil; self.string = nil; ...

  4. Matlab---从入门到精通 Chapter 4 编程基础

    ---恢复内容开始--- 4-1 M文件编辑器 在命令窗口输入edit命令,可以打开M文件编辑器,创建新的M文件 在命令行中输入edit filename,那么可以打开在当前目录环境下的M文件 4-2 ...

  5. schema文件及XML文件的DOM和Sax解析

    schema文件 <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="htt ...

  6. Android Studio 开发安卓软件时下载的工程项目 Sync with gradle 失败

    Sync with gradle 失败的原因有很多,其中很多时候会遇到下载下来的工程同步失败,目前的经验来看下载的工程同步失败均是由于下图中的两个配置其中某个缺少了 google() 或者 jcent ...

  7. NOIp2018模拟赛四十一

    现在是下午15:36,我已经改完题了...刷新纪录 A题叫B,B题叫A是什么操作??? 我离200只差一个SBFA.jpg 成绩:0+100+10=110 被虐啦...今天九个阿克的Orz.A题是个神 ...

  8. 影像服务——加载CESIUM自带的影像服务

    1.加载arcgis数据——ArcGisMapServerImageryProvider var viewer = new Cesium.Viewer("cesiumDiv",{ ...

  9. BZOJ2870 最长道路tree(并查集+LCA)

    题意 (n<=50000) 题解 #include<iostream> #include<cstring> #include<cstdio> #include ...

  10. 学习《数据科学入门》中文PDF+英文PDF+源代码

    数据科学是一个蓬勃发展.前途无限的行业,有人将数据科学家称为"21世纪头号性感职业".本书从零开始讲解数据科学工作,教授数据科学工作所必需的黑客技能,并带领读者熟悉数据科学的核心知 ...