1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Python爬虫:selenium动态加载HTML的常用方法【汇总笔记】

Python爬虫:selenium动态加载HTML的常用方法【汇总笔记】

时间:2021-08-26 02:15:52

相关推荐

Python爬虫:selenium动态加载HTML的常用方法【汇总笔记】

前言

Selenium 是一个用于Web应用程序测试的工具。

Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,GoogleChrome,Opera,Edge等。

这个工具的主要功能包括:

浏览器兼容性测试:测试应用程序看是否能够很好的工作在不同浏览器和操作系统之上;系统功能测试:创建回归测试检验软件功能和用户需求;

支持自动录制动作和自动生成.Net、Java、Perl等不同语言的测试脚本。

通过本篇,你将学会使用 selenium 动态加载HTML的技巧,包括:操作输入框,键盘,下拉条,页面跳转,标签内容读取...。

正文

Selenium 是浏览器自动测试框架,模拟浏览器,驱动浏览器执行特定的动作,并可获取浏览器当前呈现的页面的源代码,可见即可爬。正是利用了这一特点,Python 可以实现对动态页面的渲染,做到可见即可爬。

一、chromedriver 驱动安装

Selenium 相当于机器人,可以模拟人在浏览器中的行为,并自动处理浏览器中的行为,如:单击、翻页、输入数据、回车和删除cookie操作。 而 Chromedriver 是Chrome 浏览器的驱动程序,可以移动浏览器。

1. 驱动程序介绍

驱动器因浏览器而异,案例以 Chrome 浏览器为例,以下是各种浏览器及其相应的驱动程序:

2.驱动程序安装

注意:Chromedriver 要下载与本地Chrome 浏览器相对应的版本。

建议:直接使用Chromedriver 驱动的绝对路径,这样做能规避很多坑,听我的没错。

from selenium import webdriver# 指定chromedriver的绝对路径driver_path = r'C:\Users\Administrator\Desktop\chromedriver.exe'# 初始化driverdrive = webdriver.Chrome(executable_path=driver_path)# 请求页面,打开网页drive.get("/")# 通过page_source获取网页源代码print(drive.page_source)# 关闭网页drive.close()

Chromedriver 主要负责爬取动态页面的前面部分 -- 打开HTML页面,后面页面的渲染和操作,就是Selenium 的工作内容了。

二、Selenium 插件安装

在【Terminal】控制台"pip install selenium"命令导入,或者在导航栏下【Pycharm - Settings - Python Interpreter 】自动导入插件,以后者为例:

三、Selenium 常用方法

1. 获取节点信息

据说旧版本是使用【find_element_by_xx】方法获取节点,新版本已经不可用了,我目前使用的Selenium 为【4.4.3】版本:

获取单个节点信息(多个则匹配第一个):find_element(By.xx, 'xx')获取多个节点信息(加S):find_elements(By.xx, 'xx')案例:

from selenium import webdriver# 浏览器驱动from mon.by import By # 节点定位driver = webdriver.Chrome()driver.get('/')# 通过id属性获取节点driver.find_element(By.ID, 'key').send_keys("华为mate50")# 通过class属性获取节点,并触发点击事件driver.find_element(By.CLASS_NAME, 'button').click()time.sleep(5)driver.close()

HTML说明:输入框和按钮的属性分别是【id="key"】和【class="button"】

2.获取元素属性

案例:

from selenium import webdriverdriver = webdriver.Chrome()driver.get('/')el_div = driver.find_element(By.ID, 'key')print(el_div)print(el_div.get_attribute("class")) # class属性print(el_div.id) # idprint(el_div.location) # 位置print(el_div.tag_name) # 标签名print(el_div.size) # 大小print(el_div.text) # 文本

3.页面交互:搜索框输入,上下滚动下拉条,页面前进和后退

案例:

import time # 时间控制from selenium import webdriver# 浏览器驱动from selenium.webdriver import Keys# 键盘驱动from mon.by import By # 节点定位driver = webdriver.Chrome()driver.get('/')# 根据id属性获取【输入框】_input = driver.find_element(By.ID, 'key')# 标签内输入搜索内容_input.send_keys('华为mate50')# 标签内操作向上,向下翻页_input.send_keys(Keys.PAGE_DOWN)_input.send_keys(Keys.PAGE_UP)# 根据class属性获取【搜索】按钮,触发点击事件driver.find_element(By.CLASS_NAME, 'button').click()# 向下滚动到底部driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')# 向上滚动到顶部driver.execute_script('window.scrollTo(0,0)')# 向下滚动1000位置driver.execute_script('window.scrollTo(0,1000)')time.sleep(2)# 向下滚动目标元素位置script = "arguments[0].scrollIntoView();";driver.execute_script(script, driver.find_element(By.ID, 'J_bottomPage'))time.sleep(2)driver.get('/')driver.back()time.sleep(2)driver.forword()time.sleep(2)driver.close()

输入+点击的代码可以简化一下:

driver.find_element(By.ID, 'key').send_keys("华为mate50")

4. 页面等待:显式,隐式

当进入一个新的网页时,有时网页的加载并没有那没快,当网速很慢时尤其明显,特别是针对商品列表,图片类的信息,这时候是爬不到完整数据的,所以,我们需要等待页面加载完成。

等待的方式有3种:

强制等待:必须等这么久,没有任何前提条件,和页面有没有渲染无关;隐性等待:设置一个时间,在设置的时间内,如果页面加载完成了就进行下一步;如果没有加载完成,则会报超时异常;显式等待:设置一个等待时间,一个间隔时间,每隔一段时间执行下util中的方法,直到等待时间结束。

注意:虽然 time.sleep(n) 简单,但是有时设置的睡眠时间过长,干等很浪费效率的,所以一般只用在想要暂停代码查看页面效果的地方,就像案例中一样。

案例:

import time # 时间控制from selenium import webdriver# 浏览器驱动from mon.by import By # 节点定位driver = webdriver.Chrome()driver.get('/')# 根据id属性获取【搜索框】位置,输入搜索内容driver.find_element(By.ID, 'key').send_keys("华为mate50")# 根据class属性获取【搜索】按钮位置,触发点击事件driver.implicitly_wait(5)driver.find_element(By.CLASS_NAME, 'button').click()wait = WebDriverWait(driver, 10, 0.2)wait.until(EC.presence_of_element_located((By.CLASS_NAME, "p-img")))# 向下滚动到底部driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')time.sleep(3)# 向上滚动到顶部driver.execute_script('window.scrollTo(0,0)')time.sleep(3)driver.close()

5.键盘事件

6.selenium转BeautifulSoup

根据小编的开发经验,selenium 很擅长模拟和测试,它的特性是BeautifulSoup不具备的,但是对于取值操作,简单的还好,复杂点的比如循环<li>标签这种操作,我还是觉得BeautifulSoup更方便。

在爬虫的世界里,大量有价值的数据都是循环展现的,比如:某排行榜,某商品列表等...所以,selenium+BeautifulSoup的操作必不可少。

核心代码

from selenium import webdriver # 浏览器驱动from bs4 import BeautifulSoup # 解析htmldriver = webdriver.Chrome()driver.get('/')# 获取完整渲染的网页源代码pageSource = driver.page_source soup = BeautifulSoup(pageSource,'html.parser')# ...

四、注意事项

4.1no such element: Unable to locate element

在某些场景下使用selenium的 driver.find_element(By.CLASS_NAME,'xxxx') 定位web元素的时候,会提示找不到定位元素的异常,比如:我们案例中要定位的包含 class="button cw-icon" 属性的按钮。

异常原文

mon.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".button cw-icon"}

原因分析

经过认真检查,发现从web上获取的元素的class_name并没有错,问题的原因只能是多个属性间的空格“ ”不能被find_element() 识别造成的。

解决办法

针对前端代码一个标签内使用多个属性值的情况,我们只需要把class_name里面的空格间隔符替换成英文的“.”就可以了。

# 注释掉的为原方法,未注释的是修改以后的方法# driver.find_element(By.CLASS_NAME,'button cw-icon').click()driver.find_element(By.CLASS_NAME,'button.cw-icon').click()

4.2 其他 ...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。