文章目录
selenium库
selenium库是模拟浏览器,动态爬虫的一个库。首次使用需要安装
pip install selenium
安装之后导入selenium包就可以了。
import selenium
一般常用的类有:
from selenium import webdriver # 引擎
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 # 显性等待需要的参数
下面从引擎开始学习
引擎启动器
引擎相当于是,浏览器启动器,可以打开谷歌、火狐、PhantomJS(无界面浏览器)。要启动引擎,本地需要下载对应的浏览器,比如说,你想使用
driver = webdriver.Firefox()
你就必须下载火狐浏览器才可以启动引擎。
可能会出现下载完之后还是打不开火狐浏览器的情况,这是因为selenium和火狐的版本不一致导致的,需要下载一个geckodriver,放到某一个环境路径中,比如python的环境变量。将可执行文件放到里面就可以正常启动了。资源可以在我的博客中找到。
现在就打开一个引擎了,接下来访问网址url。
访问地址
访问网址非常简单。
url = 'http://www.baidu.com'
driver.get(url)
就可以了。当然还可以添加请求头,cookie,等等。在这里就不说了,因为自己现在还没有遇到需要加请求头的网站(主要是自己不会hhhh)。
切换网页,框架
有时会打开多个网页,这时可能,需要切换网页。
driver.window_handles # 会返回所有打开的网页名字
driver.switch_to_window('网页名字')
当你需要,在上一次点击之前网站,也就是网页的后退。可以使用
driver.forward() #前进
driver.back() # 后退
当然一个网页可能有不同的框架组成,定位元素时,需要切换框架才可以定位成功,这时就需要:
driver.switch_to_frame('框架的name或者id')
# 当一个框架没有name或者id属性时,可以使用以下方法:
rq = driver.find_element_by_xpath('//iframe[@scrolling="no"]') # 先定位,后切换
driver.switch_to.frame(rq)
# 跳出当前框架,返回到上一个框架
driver.switch_to.parent_frame()
# 跳到最开始的框架。
定位元素
定位元素是selenium中最重要的,因为很多操作都是对元素进行的,所以你得先找到需要操作的元素,才能继续进行。
定位元素有很多方法,其中有常用的有:
driver.find_element_by_id() # 通过id查找
driver.find_element_by_class_name() # 通过class查找
driver.find_element_by_xpath() # 根据符合xpath语法的元素查找
driver.find_element_by_link_text() # 根据完全符合文本的元素查找
driver.find_element_by_partial_link_text() # 根据包括文本的元素查找
# 返回一个元素对象,可以继续使用上面的查找方法。
# 例如driver.find_element_by_link_text('新语音呼入报表').find_element_by_id('data')
# 上面的都是找到一个符合条件的元素,就返回。在element加一个s就是找出所有符合条件的元素。
driver.find_elements_by_id()
driver.find_elements_by_class_name()
driver.find_elements_by_xpath()
driver.find_elements_by_link_text()
driver.find_elements_by_partial_link_text()
# element如果没有找到符合条件的元素,会返回一个异常。
# elements如果没有找到符合条件的元素,会返回一个空列表
当然还有暂时我用的不多的定位方法,比如:
driver.find_element_by_css_selector() # 根据css语法定位
driver.find_element_by_tag_name() # 根据标签名定位元素
driver.find_element_by_name() # 通过name这个属性定位?
还有一个总方法:
driver.find_element(by.ID,'data') # 通过id值查询
driver.find_elements(by.ID,'data') # 通过id值查询
# 这个需要使用by.(需要定位类型),结果和上面的一样。
对元素进行操作
我们现在已经定位到了一个元素了,比如:
el = driver.driver.find_element_by_id('starttime')
现在可以对这个元素进行以下常用操作:
el.click() # 点击
el.clear() # 清空值
el.send_keys('123') # 将123添加到el元素中
当然还有其他的鼠标操作:
#导入 ActionChains 类
from selenium.webdriver import ActionChains
# 鼠标移动到 ac 位置
ac = driver.find_element_by_xpath('element')
ActionChains(driver).move_to_element(ac).perform()
# 在 ac 位置单击
ac = driver.find_element_by_xpath("elementA")
ActionChains(driver).move_to_element(ac).click(ac).perform()
# 在 ac 位置双击
ac = driver.find_element_by_xpath("elementB")
ActionChains(driver).move_to_element(ac).double_click(ac).perform()
# 在 ac 位置右击
ac = driver.find_element_by_xpath("elementC")
ActionChains(driver).move_to_element(ac).context_click(ac).perform()
# 在 ac 位置左键单击hold住,点住不动
ac = driver.find_element_by_xpath('elementF')
ActionChains(driver).move_to_element(ac).click_and_hold(ac).perform()
# 将 ac1 拖拽到 ac2 位置
ac1 = driver.find_element_by_xpath('elementD')
ac2 = driver.find_element_by_xpath('elementE')
ActionChains(driver).drag_and_drop(ac1, ac2).perform()
网页等待、元素等待、元素遮蔽
有时会因为网页没有加载完成,导致元素查找不到,所以需要等一下,有三种等待,
1、显性等待
显示等待,就是等某个元素加载出来之后,再进行提取。
# WebDriverWait 库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 类,负责条件出发
from selenium.webdriver.support import expected_conditions as EC
# 每隔10秒查找页面元素 id="myDynamicElement",直到出现则返回
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "myDynamicElement")))
如果不写参数,程序默认会 0.5s 调用一次来查看元素是否已经生成,如果本来元素就是存在的,那么会立即返回。
2、隐形等待
隐式等待比较简单,就是简单地设置一个等待时间,单位为秒。
driver.implicitly_wait(10) # seconds,等待10秒,知道界面加载完成
3、暴力等待
直接使用sleep()等待,不推荐使用
import time
time.sleep(2) # 程序暂停2秒
有时元素也加载出来,但是被另一个元素遮蔽了,这时需要等待遮蔽的元素消失,再去提取元素。例如:
obscures = driver.find_elements_by_xpath('//div[@id="1E37CE2C72950001AC1115D0A939F360"]')
# obscures遮蔽元素
if obscures != []:
WebDriverWait(driver, 10).until(EC.invisibility_of_element(obscures[0]))
# 等待遮蔽元素消失
网页转换、Beautifulsoup、lxml
当我们已经进到所需要数据的网页了,这时,需要将它driver.page_source
进行转化为xml文档或者html文档,进而使用BeautifulSoup、xpath进行提取数据。
soup = BeautifulSoup(driver.page_source,'xml')
# 转化为beautifulsoup格式,使用beautifulsoup语法,提取数据。
html = etree.HTML(driver.page_source)
# 转化为xml文档,使用xpath语法,提取数据
网页关闭,引擎退出
拿到想要的数据之后,将引擎关闭。
driver.quit()
定位元素的一些注意事项
想要代码稳定,定位元素时,尽量选择这个元素唯一的值,id、class、文本,等等,有时id、class也不太稳定,那就选择文本;这一个子标签可能没有,那就查找上一级;实在不行就使用elements,判断一下是不是空列表,然后再进行提取。尽量保证百分比可以提取到元素,这样后面的代码,才可以更稳定。
其他数据保存的问题(简略介绍,以后会详细学习)
有一个需求是,保留excel的格式,只填入数据,可以使用以下方法:
import pandas as pd
from openpyxl import load_workbook
s = pd.DataFrame('要保存的数据')
#读取被写入的Excel工作簿
book = load_workbook('test.xlsx')
#建立写入对象
write = pd.ExcelWriter(r'test.xlsx', engine='openpyxl')
write.book = book
write.sheets = {ws.title: ws for ws in book.worksheets}
#写入数据
s.to_excel(write, sheet_name='分时话务量统计', header=False, index=False, startrow=3, startcol=21)
write.save()
write.close()
网页弹窗、填充表单、模拟滚动条滚动,之后再学习。