使用selenium实现动态渲染页面的爬取。selenium是浏览器自动测试框架,模拟浏览器,驱动浏览器执行特定的动作,并可获取浏览器当前呈现的页面的源代码,可见即可爬。该工具支持IE浏览器、Mozilla Firefox及Google Chrome等
。
selenium安装
通过 pip install selenium 命令安装selenium模块
下载浏览器驱动 "https://chromedriver.chromium.org/downloads"
这里需要根据已经安装的Google Chrome浏览器的版本,以及自己的电脑的系统安装浏览器驱动。
下载完成后,需要将文件保存在与python文件同级路径中,如下图所示。
如果出现如下报错。
Message: session not created: This version of ChromeDriver only supports Chrome version 79
请查看谷歌浏览器与驱动不一致解决方案。此处笔者是重新安装谷歌浏览器79版本。
声明浏览器对象
代码语言:javascript复制import os
os.chdir(r'/Users/jim/Desktop/代码')
from selenium import webdriver # 导入浏览器驱动模块
browser=webdriver.Chrome() # 会打开浏览器
selenium模块的常用方法
driver.find_element_by_
常用方法 | 描述 |
---|---|
driver.find_element_by_id() | 根据id获取节点,参数为字符类型id对应的值 |
driver.find_element_by_name() | 根据name获取节点,参数为字符类型name对应的值 |
driver.find_element_by_xpath() | 根据XPath获取节点,参数为字符类型的XPath |
driver.find_element_by_link_text() | 根据链接文本获取节点,参数为字符类型链接文本 |
driver.find_element_by_tag_name() | 根据节点名称获取节点,参数为字符类型的节点名称 |
driver.find_element_by_class_name() | 根据class获取节点,参数为字符类型class对应的值 |
driver.find_element_by_css_selector | 根据CSS选择器获取节点,参数为字符类型的CSS选择器语法 |
如需要获取符合条件的多个节点时,在对应方法中element后面添加s。
driver.find_element(by='id', value=None)
by: 获取节点的方式
value: 获取方式对应的值(理解为条件)
获取多个节点时使用find_elements()
By属性 | 用法 |
---|---|
By.ID | 根据id值获取对应的节点 |
By.LINK_TEXT | 根据链接文本获取对应的节点 |
By.PARTIAL_LINK_TEXT | 根据部分链接文本获取对应的节点 |
By.NAME | 根据name值获取对应的单个或多个节点 |
By.TAG_NAME | 根据节点名获取节点 |
By.CLASS_NAME | 根据class值获取节点 |
By.CSS_SELECTOR | 根据CSS选择器获取节点,对应的value字符串字符串CSS位置 |
By.XPATH | 根据By.XPATH获取节点,对应的value字符串节点位置 |
获取某个节点中的某个属性对应的值时,可以使用get_attribute()方法
来实现。
例
代码语言:javascript复制#根据name
_input=browser.find_element_by_name("q")
#根据css获取,id名
input_second=browser.find_element_by_css_selector("#q")
#根据id获取
input_third=browser.find_element(By.ID,"q")
打开百度浏览器,并查找元素
通过选择元素按钮找到百度搜索框的HTML代码,这里通过他的id='kw'
寻找到浏览框,输完内容后需点击"百度一下"id='su'
import time
from selenium import webdriver
browser=webdriver.Chrome()#会打开浏览器
browser.get('https://www.baidu.com/')
_input = browser.find_element_by_id('kw')#找百度的输入框
# print(_input)
_input.send_keys('python')
_input=browser.find_element_by_id('su').click()#回车
time.sleep(10)
browser.close()#关闭浏览器
效果图如下
获取元素信息,获取属性
代码语言:javascript复制#获取元素信息,获取属性
from selenium import webdriver
browser=webdriver.Chrome()
url="https://www.zhihu.com/explore"
browser.get(url)
logo=browser.find_element_by_class_name("ZhihuLogoLink")
print(logo)
print(logo.get_attribute("class"))
print(logo.text)
print(logo.id) #id
print(logo.location) #位置
print(logo.tag_name) #标签名
print(logo.size) #大小
<selenium.webdriver.remote.webelement.WebElement (session="b07f3d23e5f830581deddfa8a568631c", element="71a5b5b9-dc75-4bac-846a-484ba879ac48")> ZhihuLogoLink 71a5b5b9-dc75-4bac-846a-484ba879ac48 {'x': 16, 'y': 10} a {'height': 33, 'width': 64}
元素交互、下拉进度条
先找到搜索框位置,和点击搜索位置
代码语言:javascript复制import time
from selenium import webdriver
browser=webdriver.Chrome() #打开浏览器
browser.get('https://www.jd.com/?cu=true&utm_source=baidu-pinzhuan&utm_medium=cpc&utm_campaign=t_288551095_baidupinzhuan&utm_term=0f3d30c8dba7459bb52f2eb5eba8ac7d_0_27b1bb5bc1cb4d2faf65fc59cdbfd1cc')
_input=browser.find_element_by_id('key')#
_input.send_keys('羽绒服')
_input.clear()
_input.send_keys('aj')
browser.find_element_by_class_name('button').click()#回车
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
browser.execute_script('window.scrollTo(0,0)')
#browser.close()#关闭浏览器
结果动态演示
等待
当进入一个网站时,网页刷新没有那么快,文字先出来,图片后出来。当网速很慢时尤其明显,因此此时需要加入等待,等待分两种,一种是隐式等待,一种是显示等待。
隐式等待
即等待固定的时间
代码语言:javascript复制from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
browser.implicitly_wait(3) # 等待固定时间
_input = browser.find_element_by_class_name('zu-button-more')
显示等待
根据实际情况,可设置最大等待时间,知道某个目标元素加载完成。
代码语言:javascript复制from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.get('https://www.taobao.com/')
wait = WebDriverWait(browser,10) # 最多等待十秒
# 等待到id='q'加载完成
_input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
# 等待到'.btn-search'可以点击
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
浏览器的前进和后退
代码语言:javascript复制from selenium import webdriver
import time
browser=webdriver.Chrome()
browser.get("https://www.taobao.com")
time.sleep(2)
browser.get("https://www.baidu.com")
browser.back()#后退
time.sleep(2)
browser.forward()#前进
time.sleep(3)
browser.refresh()#刷新
time.sleep(3)
browser.close()
选项卡管理
代码语言:javascript复制from selenium import webdriver
import time
browser=webdriver.Chrome()
browser.get("https://www.zhihu.com/explore")
browser.execute_script("window.open()")
print(browser.window_handles)
browser.switch_to_window(browser.window_handles[1])
browser.get("https://www.taobao.com")
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.get("https://www.jd.com")
browser.close()
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.close()
异常处理
代码语言:javascript复制from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException
browser=webdriver.Chrome()
try:
browser.get("https://www.zhihu.com/explore")
except TimeoutException:
print("Time out")
try:
browser.find_element_by_id("hello")
except NoSuchElementException:
print("No Element")
finally:
browser.close()
常用操作
代码语言:javascript复制#常用键的操作
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
time.sleep(3)
driver.find_element_by_id('kw').send_keys('selenium')
#在搜索框中输入"selenium"
time.sleep(3)
driver.find_element_by_id('kw').send_keys(Keys.SPACE)
#输入空格键
time.sleep(3)
driver.find_element_by_id('kw').send_keys('python')
#在搜索框中输入"python"
time.sleep(3)
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')
#输入Control a模拟全选
time.sleep(3)
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'c')
#输入Control c模拟复制
time.sleep(3)
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'v')
#输入Control v模拟粘贴
time.sleep(3)
driver.find_element_by_id('kw').send_keys(Keys.ENTER)
#输入回车代替点击搜索按钮
time.sleep(3)
driver.close()
下面是一些常用的键盘事件
代码 | 含义 |
---|---|
Keys.BACK_SPACE | 回退键(BackSpace) |
Keys.TAB | 制表键(Tab) |
Keys.ENTER | 回车键(Enter) |
Keys.SHIFT | 大小写转换键(Shift) |
Keys.CONTROL | Control键(Ctrl) |
Keys.ALT | ALT键(Alt) |
Keys.ESCAPE | 返回键(Esc) |
Keys.SPACE | 空格键(Space) |
Keys.PAGE_UP | 翻页键上(Page Up) |
Keys.PAGE_DOWN | 翻页键下(Page Down) |
Keys.END | 行尾键(End) |
Keys.HOME | 行首键(Home) |
Keys.LEFT | 方向键左(Left) |
Keys.UP | 方向键上(Up) |
Keys.RIGHT | 方向键右(Right) |
Keys.DOWN | 方向键下(Down) |
Keys.INSERT | 插入键(Insert) |
DELETE | 删除键(Delete) |
NUMPAD0 ~ NUMPAD9 | 数字键1-9 |
F1 ~ F12 | F1 - F12键 |
(Keys.CONTROL, ‘a’) | 组合键Control a,全选 |
(Keys.CONTROL, ‘c’) | 组合键Control c,复制 |
(Keys.CONTROL, ‘x’) | 组合键Control x,剪切 |
(Keys.CONTROL, ‘v’) | 组合键Control v,粘贴 |
登录操作
代码语言:javascript复制browser=webdriver.Chrome()
url='''
https://passport.jd.com/new/login.aspx?
ReturnUrl=https://www.jd.com/?cu%3
Dtrue&utm_source=baidu-pinzhuan&utm_me
dium=cpc&utm_campaign=t_288551095_baid
upinzhuan&utm_term=0f3d30c8dba7459bb52f2
eb5eba8ac7d_0_5c595fde6f6743c1a1878bfeaf4f21
5f'''
browser.get(url)
time.sleep(3)
button=browser.find_element_by_link_text('账户登录').click()
browser.find_element_by_id('loginname').send_keys('')#自己的用户名
time.sleep(2)
browser.find_element_by_id("nloginpwd").send_keys('')#密码
time.sleep(2)
browser.find_element_by_id('loginsubmit').click()#登录