第7章 动态渲染页面的爬取---1、Selenium的使用

除了Ajax这种JavaScript动态渲染的页面外,还要一些,比如分页部分由JavaScript生成,并非原始HTML代码,还有的比如淘宝页面,即使是Ajax获取数据,但其接口含有加密参数,很难爬取。但是我们找到了:Selenium、Splash、PyV8、Ghost等,实现了可见即可爬取。

Selenium,可以驱动浏览器进行点击、下拉等操作,还做到可见即可爬取。

首先,安装Selenium和ChromeDriver

pip安装
pip3 install selenium

wheel安装,可百度搜索即可获取。

selenium安装成功后,还需要浏览器(如Chrome)来配合工作,安装ChromeDriver。
打开浏览器,帮助栏内查看关于Google Chrome,查看版本号,然后网上搜索进入Chrome Driver官网,根据自己版本号下载对应的Driver。
将下载好的exe文件,放到Python的Scripts目录下。

以上操作,可通过下列语句进行验证是否正确:
from selenium import webdriver
browser = webdriver.Chrome()



 
  • 声明浏览器对象

声明浏览器对象,有Chrome、Firefox、Edge等,还支持无界面浏览器PhantomJS.初始化如下:

from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.PhantomJS()
browser= webdriver.Safari()
  • 访问页面
from selenium import webdriver

browser=webdriver.Chrome()
browser.get('http://www.baidu.com')
print(browser.current_url) # 当前访问页面的链接
print(browser.get_cookies()) # 当前的Cookies
print(browser.page_source) # 当前网页的源代码
browser.close() #浏览器自己关闭

上述过程,就是通过Selenium来驱动浏览器加载网页,直接获取到了Javascript渲染的结果,不存在使用什么加密系统了的。

  • 查找结点
## 单个结点,结点的属性通过源代码观察获取。
input_first=browser.find_element_by_id('q')#根据ID
input_secsone=browser.find_element_by_css_selector('q')#根据CSS选择器
input_third=browser.find_element_by_xpath('//*[@id="q"]')#根据Xpath获取
print(input_first,input_secsone,input_third)
# 这三个节点都是WebElement类型

## 所有获取单个节点的方法
find_element_by_id()
find_element_by_name()
find_element_by_xpath()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_tag_name()
find_element_by_class_name()
find_element_by_css_selector()

## 通用方法、find_element()传入两个参数:查找方式By和值
find_element_by_id() 等价于 find_element(By.ID,'id')#查找ID='id'的值

## 多个节点
find_elements()
lis=find_elements_by_css_selector('.service-bd li')
# 查找当前service-bd节点下的所有li节点
print(lis)

find_elements_by_id()
find_elements_by_name()
find_elements_by_xpath()
find_elements_by_link_text()
find_elements_by_partial_link_text()
find_elements_by_tag_name()
find_elements_by_class_name()
find_elements_by_css_selector()
## 同样还可以这么操作
lis = browser.find_elements(By.CSS_SELECTOR,'.service-bd li')
  • 节点交互

Selenium驱动浏览器执行一些操作,比如:输入文字send_keys()方法、清空文字clear()方法、点击按钮click()方法。

input=browser.find_element_by_id('q')#寻找到输入框
input.send_keys('iphone')#输入文字
time.sleep(1)
input.clear()#输入框清空
input.send_keys('iPad')
button=browser.find_element_by_class_name('btn-search')#寻找到搜索点击按钮
button.click()#点击开始搜索
  • 动作链

鼠标拖曳、键盘按键等动作链。

  • 执行JavaScript

下拉进度条,弹窗显示等通过execute_script方法,该方法可以实现API没有提供的所有功能。

from selenium import webdriver
import time
browser= webdriver.Chrome()
browser.get ('https://www.zhihu.com/explore')
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')#下拉至底部
browser.execute_script('alert("To Bottom")')#弹窗显示,已经到底部
time.sleep(3)
browser.close()
  • 获取节点信息
  • 获取属性
# 通过get_attribute()方法,前提是先选中这个节点,再使用get_attribute方法
from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver. Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
logo= browser.find_element_it_by_id('zh-top-link-logo')#选中知乎logo,该节点
print(logo)
print(logo.get_attribute('class'))#打印选中的节点中class属性的名称是多少
  • 获取文本值

每个WebElement节点都有text属性,直接使用.text可得到节点内部的文本信息,相当于Beautiful Soup的get_text()方法、pyquery的text()方法。

## 获取文本值
input = browser.find_element_by_class_name('zu-top-add-question')# 选中'提问'按钮这个节点
print(input.text)
  • 获取id、位置、标签名和大小
# 比如 id 属性可以获取节点id,
# location 属性可以获取该节点在页面中的相对位置
# tag_name 属性可以获取标签名称
# size 属性可以获取节点的大小

from selenium import webdriver
browser = webdriver.Chrome()
url='http://www.zhihu.com/explore'
browser.get (url)
input= browser.find_element_by_class_name ('zu-top-add-question')
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)
  • 切换frame

这个知识点也是比较迷,后续遇到再做深化吧!

import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
browser = webdriver.Chrome()
url='http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult')# 该方法切换到子Frame
try:
    logo= browser.find_element_by_class_name('logo')# 尝试获取父级Frame里的logo节点
except NoSuchElementException:# 肯定是找不到的,因为已经切换到了子级Frame
    print('NO LOGO')

browser.switch_to.parent_frame()
logo = browser.find_element_by_class_name('log')
print(logo)
print(logo.text)
browser.close()
  • 延时等待

分为隐式等待和显式等待。

  • 隐式等待

当查找结点时而节点并没有立即出现的时候,隐式等待将等待一段时间再查找DOM,默认时间为0.

from selenium import webdriver
browser = webdriver.Chrome()
browser.implicitly_wait (10)#隐式等待
browser.get('https://www.zhihu.com/explore' )
input = browser.find_element_by_class_name ('zu-top-add-question')
print(input)
  • 显式等待

规定一个固定时间,而页面的加载时间会受到网络条件的影响。故,指定要查找的节点,然后指定最长等待时间。如果在规定时间内加载出来该节点,就返回节点;到了规定时间还没有加载出来,则抛出异常。

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)# 指定最长时间
input = wait.until(EC.presence_of_element_located((By.ID,'q')))# 指定等待条件
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'btn-search')))
print(input,button)
browser.close()

隐式等待:先查找节点,若未加载到该节点,则等待T,T内若还未加载到,则抛出异常。

显式等待:先指定节点,再等待固定时间T,T内加载则正常。否则异常

关于等待条件,下列表中列出了所有的等待条件:

  • 前进和后退

Selenium可对浏览器完成back()后退,forward()前进。

# 前进和后退
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser. get ('https://www.baidu.com/')
browser.get('https://www.taobao.com/')
browser.get('https://www.hao123.com/')
browser.back()
time.sleep(1)
browser.forward()
browser.close()
  • Cookie

使用Selenium还可以对Cookies进行获取、添加、删除等操作。

# Cookie
from selenium import webdriver
browser=webdriver.Chrome()
browser.get('http://www.zhihu.com/explore')
print(browser.get_cookies())
browser.add_cookie({'name':'name','domain':'www.zhihu.com','value':'germy'})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())
  • 选项卡管理

访问页面就会开启一个选项卡。在selenium中,对选项卡进行操作:

# 选项卡
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.execute_script('window.open()')# 在第一个选项卡内打开一个页面,百度
print(browser.window_handles)
browser.switch_to_window(browser.window_handles[1])# 1=第二个选项卡打开淘宝
browser.get('https://www.taobao.com')
time.sleep(3)
browser.switch_to_window(browser.window_handles[0])# 0=第一个选项卡打开hao123
browser.get('https://www.hao123.com')
browser.close()
  • 异常处理

try except语句来捕获各种异常

from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException
browser = webdriver.Chrome()
try:
    browser. get ( 'https://www.baidu.com')
except TimeoutException:
    print('Time out')
try:
    browser . find_element_by_id('hello')
except NoSuchElementException:
    print('No Element')
finally:
    browser.close()

Selenium、节点交互、切换Frame、延时等待、Cookie

发布了92 篇原创文章 · 获赞 23 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Pit3369/article/details/86652122
今日推荐