本次介绍爬虫中常用到到selenium
库及其操作
1⃣️selenium
入门
先来看一个简单到selenium模拟器请求页面到代码:
from selenium import webdriver
broswer = webdriver.Chrome()
broswer.get('https://www.tmall.com')
# 通过page_soucre获取页面文本
print(broswer.page_source)
如果用requests库来进行操作:
import requests
resp = requests.get('https://www.tmall.com')
# 通过text获取页面文本
print(resp.text)
如果我们再打印一下页面文本到长度:
print(len(resp.text))
print('*'*20)
print(len(broswer.page_source))
211451
********************
398720
总结一下:
-
requests
:一次请求加载数据少,但是请求速度快; -
selenium
:请求数据多,会加载js,但是速度慢 - 其他:
- 无论
selenium
还是requests
库,都可以获取页面等源码或者文本; - 再进行
xpath
或者beautifulsoup
来解析获取数据
- 无论
2⃣️selenium
五种元素定位方法
- 通过
class name
定位元素,可以是一个元素本身,或者返回元素构成到列表
# find_element_by_class_name,获取一个元素,返回值为元素本身
ele = br.find_element_by_class_name("s-combobox-input")
# 因为是元素,所以可获得元素属性
ele.size
# find_elements_by_class_name,获取多个元素,返回一个列表
eles = br.find_elements_by_class_name("s-combobox-input")
# 因为是列表,可迭代,每项是元素本身
for i in eles:
print(i)
- 通过
xpath
定位元素,可以是一个元素本身,或者返回元素构成到列表
print(br.find_elements_by_xpath('//*[@id="mq"]'))
- 通过
html
元素的id
定位元素
# id是唯一的,通常是id直接查找某个元素本身
print(br.find_element_by_id("mq"))
- 通过
tag name
和name
定位元素
# 举例子:tag name
# print(br.find_elements_by_tag_name('input'))
for i in br.find_elements_by_tag_name('input'):
print(i.size)
# name 是标签内部属性的名称
# input type="text" name="q"
print(br.find_element_by_name('q'))
总结五种方法如下:
- find_element_by_id
- find_elements_by_tag_name
- find_elements_by_name
- find_elements_by_class_name
- find_elements_by_xpath
3⃣️selenium
对数据填充和页面数据提取
以input
元素为例填充数据
- 首先,获取元素,根据上面说的的元素定位方式
- 然后,先清楚输入框中旧数据
clear()
方法,在通过send_keys()
方法发送输入文本 - 补充,输入框常用元素:
input/ textarea
示例代码如下:
# 创建浏览器驱动,并打开页面
from selenium import webdriver
br = webdriver.Chrome()
br.get('https://www.tmall.com')
# 获取元素
input_element = br.find_element_by_id("mq")
# 清空数据后,传入要输入的文本
input_element.clear()
input_element.send_keys("Macbook pro")
再来一个关于点击操作对示例
search_button = br.find_element_by_xpath('//*[@id="mallSearch"]/form/fieldset/div/button')
search_button.click()
获取页面中数据
# 导入lxml库,解析selenium获取的页面源码
from lxml import etree
html_str = etree.HTML(br.page_source)
# 使用xpath获取商品div元素
products_div = html_str.xpath('//*[@id="J_ItemList"]/div')
# 在商品div元素中,定位所需要的数据
for item in products_div:
title = item.xpath('./div/div[2]/a/@title')
price = item.xpath('./div/p/em/@title')
shop_name = item.xpath('.//a[@class="productShop-name"]/text()')
print(shop_name, title, price)
4⃣️selenium
执行js代码
# 导入selenium库
from selenium import webdriver
br = webdriver.Chrome()
url = 'https://list.tmall.com/search_product.htm?q=%B1%CA%D0%BE&type=p&vmarket=&spm=875.7931836%2FB.a2227oh.d100&from=mallfp..pc_1_searchbutton'
br.get(url)
# js代码寻找元素,执行点击操作
js = '''
hrefs = document.getElementsByClassName('ui-page-next')
hrefs[0].click()
'''
# 使用selenium同步执行js代码
br.execute_script(js)
# 关闭浏览器窗口
br.quit()
5⃣️selenium
管理浏览器标签页
通过js代码新建浏览器标签
- 用到js代码如下:
window.open(url)
br2 = webdriver.Chrome()
br2.get('http://www.spbeen.com/')
# 通过selenium元素定位方法获取元素
ahrefs = br2.find_elements_by_xpath(".//a[contains(text(), 'Python3教程')]")
# 获取html元素属性值
# 使用js新建标签页,创建新标签
for ahref in ahrefs:
js = 'window.open("{}")'.format(ahref.get_attribute('href'))
br2.execute_script(js)
查看当前标签页
# 查看全部标签页ID
br1.window_handles
# 当前程序使用的标签页ID,与鼠标操作的标签也不是同一个
br1.current_window_handle
['CDwindow-B534330C3BB5649B7F6C4C35CD7008A2',
'CDwindow-4E05180212508010415A6BB0361EA547',
'CDwindow-73A23238ECBC7ABA5C227983B6785028']
'CDwindow-B534330C3BB5649B7F6C4C35CD7008A2'
切换标签页
- 用for循环切换
- 用判断语句,判断标签页ID是否是当前标签页ID,不是的话用切换代码
# 举例:首页有2个python3教程的a元素,其他标签页有3个python3教程的a元素
print(len(br1.find_elements_by_xpath(".//a[contains(text(), 'Python3教程')]")))
# 切换标签页,然后再看看元素长度
br1.switch_to.window('CDwindow-4E05180212508010415A6BB0361EA547')
print(len(br1.find_elements_by_xpath(".//a[contains(text(), 'Python3教程')]")))
关闭标签页
br1.close()
6⃣️selenium
一些配置
无头浏览器
不启动浏览器窗口,只在后台开启进程
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
br = webdriver.Chrome(chrome_options=chrome_options)
懒加载
from selenium import webdriver
br = webdriver.Chrome()
br.get('https://www.tmall.com')
# 懒加载:禁止浏览器加载图片
options = webdriver.ChromeOptions()
prefs = {}
prefs['profile.managed_default_settings.iamges'] = 2
options.add_experimental_option('prefs', prefs)
br2 = webdriver.Chrome(options=options)
br2.get('https://www.tmall.com')
IP代理
from selenium import webdriver
options = webdriver.ChromeOptions()
# 通过options变量配置无头浏览器,配置代理,配置禁止加载js
options.add_argument('--proxy-server=http://120.198.230.15:8080')
br = webdriver.Chrome(options=options)
br.get('http://www.spbeen.com/tool/request_info/')
控制浏览器最大化
br3 = webdriver.Chrome() #默认,非全屏窗口
# 1: 通过最大化窗口方法
br3.maximize_window()
br3.quit()
# 2: 通过配置参数,初始化等时候直接最大窗口展示
options = webdriver.ChromeOptions()
options.add_argument('start-maximized')
br4 = webdriver.Chrome(options=options)
7⃣️selenium
控制iframe
一般情况下,浏览器中可定位对元素,有些在iframe中无法被代码定位。因为iframe相当于网页中嵌套网页,所以需要切换窗口来访问iframe中页面元素。
from selenium import webdriver
br = webdriver.Chrome()
br.get('https://study.163.com/')
# 自动化关闭学习兴趣弹窗
# 获取元素,执行点击操作
a_close_eles = br.find_elements_by_xpath('.//a[@class="ux-modal_close"]')
a_close_eles[0].click()
# 点击“登陆”按钮,出发iframe弹窗
a_login_eles = br.find_elements_by_xpath('.//a[@id="j-index-nav-login"]')
a_login_eles[0].click()
# 获取iframe表单内的表单input元素
# .//*[@id="account-box"]/div[2]/input这个在浏览器中可检索出来,现在用代码尝试focus
# br.find_element_by_xpath('.//*[@id="account-box"]/div[2]/input')
# 报错,无法定位元素no such element: Unable to locate element
# 目前br变量实在一开始的html标签窗口中,不会对iframe标签(另一个html标签窗口)内对元素进行检索, 需要控制br跳转到iframe标签窗口中才能定位元素
# 如何解决
# 1.定位所需要查找对元素所在iframe标签窗口
# 2.切换到iframe标签窗口
# 3.获取元素对方法,id xpath等定位元素,再进行操作即可
# 定位iframe标签元素
login_iframe = br.find_element_by_xpath('.//div[@id="j-ursContainer-0"]/iframe')
# 切换当前标签到iframe元素
br.switch_to.frame(login_iframe)
# 再来根据元素定位方法寻找input元素,,即用户名
login_input = br.find_element_by_xpath('.//*[@id="account-box"]/div[2]/input')
# 写入input元素内容
login_input.clear()
login_input.send_keys('study163@126.com')
# 寻找输入密码input元素
pwd_input = br.find_element_by_xpath('.//div[@class="inputbox"]/div[@class="u-input box"]/input[@name="password"]')
pwd_input.send_keys('12345670')
# 寻找登陆按钮元素
login_button = br.find_element_by_xpath('.//div[@class="f-cb loginbox"]/a[@id="dologin"]')
login_button.click()
# 关闭浏览器
br.close()
网友评论