selenuim最初是一个自动化测试工具,在爬虫中使用它是为了解决requests无法直接执行动态加载JavaScript代码的问题。它通过浏览器驱动程序直接驱动浏览器操作,也可以解决一部分反爬虫的问题。注意,selenium必须搭配time库使用。在用selenium做JavaScript渲染时,要用time.sleep()来延缓几秒确保渲染完成。
1.引入selenium库下的webdriver类:
from selenium import webdriver
2.实例化一个浏览器对象命名为bro(这里浏览器选择了chorme,也可以用别的),同时为webdriver设定浏览器驱动路径executable_path、浏览器参数chrome_options:
bro = webdriver.Chrome(executable_path=r'./chromedriver',chrome_options=option)
此处路径的./表示了当前目录,即驱动程序应与python文件放在一起
参数option事先设置好。先实例化option:option = webdriver.ChromeOptions(),再向option中用add_argument()方法、add_experimental_option()方法加入规则。规则有:
option.add_argument(’–headless’) #使浏览器无可视化界面,爬虫在后台运行
option.add_argument(’–disable-gpu’) #禁用浏览器的gpu加速
option.add_argument("–disable-blink-features=AutomationControlled") #规避网站对selenium的检测
等等
3.用该浏览器对象bro对浏览器进行操作。操作方法有:
(1)发起请求,取得源码
bro.get('要请求的url')
page_text = bro.page_source #page_source获取浏览器当前页面的页面源码数据。之后可用xpath、bs4对该源码进行解析
(2)标签定位:selenium拥有基于find的一系列定位的方法。这里的定位就不是为了取得源码的数据了(也可以定位到后加上.text来获取标签中文本内容),而是依据标签对浏览器进行操作。
定位法有:searched=bro.find_element_by_id()/class_name()/xpath()/tag_name()/css_selector()/link_text().......
他们分别是用id名、class属性名(class属性中存在空格时则说明有多个属性值,只能取其一,返回值为列表)、xpath路径、tag标签名(低效率不建议使用)、css选择器(类似class定位,找到属性后在前面加上一点写入即可)、超链接文本名来定位网页中的内容
若是定位不到某处标签,则可能该处标签是JavaScript加载,可用time库暂停2秒再次定位
还有一种基于普通文本定位的方法。先xpath到该文本的父标签,再在xpath路径后面添加//[text()=‘文本内容’]*
(3)网页动作链操作:
from selenium.webdriver import ActionChains #导入selenium自带的网页动作类
bro.switch_to.frame('xxx') #切换作用域到有嵌入式网页所在区域.嵌入式网页的源码有自己的#document和,其中xxx必须是嵌入式标签内部的id值
action = ActionChains(bro) #实例化一个动作对象,目标为浏览器对象bro,命名为action
div = bro.find_element_by_id('draggable') #用id搜索找到要做出动作的滑块的标签,写入div变量中
action.click_and_hold(div) '''对action进行操作。方法有click()(鼠标点击,括号里写作用的div变量)、click_and_hold()(鼠标点击且长按,括号里写作用的div变量)、move_by_offset(x,y)(鼠标以当前位置为原点偏移x、y坐标,默认是网页原点,可以搭配click切换原点,若难以寻找到标签可用坐标去点击.)、drag_and_drop_by_offset(目标标签,x,y)(拖动并放置目标标签偏移x、y个像素)、move_to_element_with_offset(用find方法找到的标签变量如上面的searched, x, y)(鼠标移动到指定标签对应的区域的x、y坐标处,并非整个网页对应的xy坐标)、release()(松开鼠标,只用于点击且长按操作后面)等等。在最后一个动作(一般是release)后面写下.perform(),这样动作链才会执行'''
动作链最好写在for循环里,因为有的操作会基于上一次的坐标累计,故在for循环中最好每次重新创建action动作对象
(4)标签交互:对定位到的标签searched传入操作。
searched.send_keys('xxx') #若searched是个输入框,则向输入框中输入xxx
searched.click() #若searched是个按钮,则点击.其中context_click()为右键点击.可用于测试网页中某点坐标
searched.screenshot('./a.jpg') #对标签所属区域截图,若把searched改为bro,则为全网页截图
(5)执行js程序:比如滚动窗口
bro.excute_script('window.scrollTo(0,document.body.scrollHeight)')
这里window.scrollTo(x,y)意为横向滚动x,纵向滚动y个像素。y取document.body.scrollHeight意为滚动一整个屏幕的像素
(6)使浏览器后退、前进、窗口最大化、窗口最小化:
bro.back()
bro.forward()
bro.maximize_window()
bro.minimize_window()
(5)关闭浏览器:bro.quit()