热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python爬虫之动态渲染页面抓取(Selenium)的使用

我们在爬虫的过程中,有一些动态渲染的页面,我们是请求不到数据的。因此,我们可以直接通过使用模拟浏览器运行的方式实现,那么就可以实现原本浏览器中可以看到的,抓取的数据就是什么样,即所

  我们在爬虫的过程中,有一些动态渲染的页面,我们是请求不到数据的。因此,我们可以直接通过使用模拟浏览器运行的方式实现,那么就可以实现原本浏览器中可以看到的,抓取的数据就是什么样,即所见即所"得"(爬);此时我们不用再去关心网页中JS使用了什么算法或者结构实现了页面渲染。

  Python提供了许多模拟浏览器运行的库,如 Selenium、 Splash、 PyV8, Ghost等

Selenium 的使用

  Selenium是一个 自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作, 同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。

1、基本使用

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

browser = webdriver.Chrome()
try:
    browser.get('https://www.baidu.com')
    # 找到输入框,根据id获取
    input = browser.find_element_by_id('kw')
    #输入搜索关键字“python”
    input.send_keys('Python')
    #点击搜索
    input.send_keys(Keys.ENTER)
    #等待十秒
    wait = WebDriverWait(browser, 10)
    # presence_of_element_located判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见。
    # 里面要是一个元祖
    wait.until(EC.presence_of_element_located((By.ID, 'content_left')))
    #输出当前url
    print('输出当前url:\n',browser.current_url)
    #输出页面COOKIE
    print('输出页面COOKIE:\n',browser.get_COOKIEs())
    #输出页面内容
    #print(browser.page_source)
except:
    print('Fail')
finally:
    #关闭浏览器
    browser.close()

输出结果:

输出当前url:
 https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=Python&fenlei=256&rsv_pq=cb2816e900015d95&rsv_t=b787r%2BVzA0qjW4QKdzHIo7fcG4iLmC6iSRyKMpiaMrmd7hA5tADIT4yrLIw&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=6&rsv_sug2=0&rsv_btype=i&inputT=213&rsv_sug4=213
输出页面COOKIE:
 [{'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BDSVRTM', 'path': '/', 'secure': False, 'value': '174'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '32292_1441_32355_31253_32348_32045_32116_31321_32297_26350_22158'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'PSINO', 'path': '/', 'secure': False, 'value': '2'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_CK_SAM', 'path': '/', 'secure': False, 'value': '1'}, {'domain': '.baidu.com', 'expiry': 1627052281, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': '6C9B8822C3C4362FD97A588E493398C8:FG=1'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'delPer', 'path': '/', 'secure': False, 'value': '0'}, {'domain': '.baidu.com', 'expiry': 3742999928, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': '6C9B8822C3C4362F3E16CA0A76797398'}, {'domain': '.baidu.com', 'expiry': 3742999928, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1595516283'}, {'domain': 'www.baidu.com', 'expiry': 1595518875, 'httpOnly': False, 'name': 'H_PS_645EC', 'path': '/', 'secure': False, 'value': 'a511pVLQtJh0hvfLuFVtXamctKD8jDLY2Z%2F0BAk49CMoxm8HDM01bvGqCLk'}, {'domain': 'www.baidu.com', 'expiry': 1596380281, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}]

2、 声明浏览器对象

from selenium import webdriver

browser = webdriver.Chrome()  # google
browser = webdriver.Firefox()  # 火狐
browser = webdriver.Edge() #edge
browser = webdriver.PhantomJS()  # ***面
browser = webdriver.Safari()  # mac自带浏览器

3、访问页面

from selenium import webdriver
browser = webdriver.Chrome()
# 通过get(url)
browser.get('https://www.taobao.com')
#打印淘宝首页页面内容
print(browser.page_source)
#关闭谷歌浏览器
browser.close()

结果:

………………(省略一万字)
  "utf-8">
  "X-UA-Compatible" cOntent="IE=edge,chrome=1">
  "renderer" cOntent="webkit">
  
………………(省略一万字)

4、 查找节点

目的:找到输入框

单个节点的情况

以淘宝为例:

python爬虫之动态渲染页面抓取-(Selenium)的使用

代码:

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
#找搜索框--id方式
input_first = browser.find_element_by_id('q')
#找搜索框--css方式
input_secOnd= browser.find_element_by_css_selector('#q')
#找搜索框--xpath方式
input_third = browser.find_element_by_xpath('//*[@>)
print(input_first)
print(input_second)
print(input_third)
browser.close()

结果:

"21a8b4b733264fbcbd8b058a2b05bf9f", element="3de372cc-d9f3-49c7-b423-e586f6a225d1")>
"21a8b4b733264fbcbd8b058a2b05bf9f", element="3de372cc-d9f3-49c7-b423-e586f6a225d1")>
"21a8b4b733264fbcbd8b058a2b05bf9f", element="3de372cc-d9f3-49c7-b423-e586f6a225d1")>

多个节点的情况

find_element() 只能查找目标网页中的一个,要查找多个要用find_elements()

代码

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
lis = browser.find_elements_by_css_selector('.service-bd li')
print(lis)
browser.close()

结果:

["bdc3c2c445ccff47c45a623f6de58563", element="68843b38-2f7a-4d6f-b600-a41709370931")>, "bdc3c2c445ccff47c45a623f6de58563", element="ba76c6b5-8e5e-49e2-930c-31dd008746e4")>, "bdc3c2c445ccff47c45a623f6de58563", element="39a9722b-d954-428a-b457-6f3b2e2ebc03")>, "bdc3c2c445ccff47c45a623f6de58563", element="5ebb0c1e-a0e4-4b44-8d53-fc6fffddb54c")>, "bdc3c2c445ccff47c45a623f6de58563", element="13abdd53-44ae-4664-a5ea-eab06fde3d8e")>, "bdc3c2c445ccff47c45a623f6de58563", element="071103dd-db53-4c32-81ae-14fe2f260842")>, "bdc3c2c445ccff47c45a623f6de58563", element="d2b29103-f42b-4417-bce2-23fac105f117")>, "bdc3c2c445ccff47c45a623f6de58563", element="d43cb5a5-2543-4da0-8e5b-5044f17b53f4")>, "bdc3c2c445ccff47c45a623f6de58563", element="577b5b36-e836-4d8d-94cd-e84f9ea06d96")>, "bdc3c2c445ccff47c45a623f6de58563", element="10850d3c-f7dd-4a7f-9691-362464092fa9")>, "bdc3c2c445ccff47c45a623f6de58563", element="358a0778-591b-427d-aa61-c2b910ba35d1")>, "bdc3c2c445ccff47c45a623f6de58563", element="7db19a0b-f4dd-476e-9d93-54a1ffb44468")>, "bdc3c2c445ccff47c45a623f6de58563", element="ce274c07-94f1-4b4e-8f9c-0fd4d993a7c3")>, "bdc3c2c445ccff47c45a623f6de58563", element="358aad1b-8fa4-48f7-8424-3720e48925eb")>, "bdc3c2c445ccff47c45a623f6de58563", element="b5d4a744-9b88-493e-8343-b57b74ca1030")>, "bdc3c2c445ccff47c45a623f6de58563", element="d709c785-03b3-4cf2-9c98-af3eff5381a1")>]

5、节点交互

输入文字:send_keys()

清空文字:clear()

点击按钮:click()

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input = browser.find_element_by_id('q')
#输入文字‘iPhone’
input.send_keys('iphone')
#睡1秒
time.sleep(1)
#清空
input.clear()
#输入文字‘iPad’
input.send_keys('ipad')
#找到class='btn-search'的按钮
button = browser.find_element_by_class_name('btn-search')
#点击它
button.click()

结果:

淘宝要登录,这里无法返回结果

6、动作链

执行鼠标拖曳 、 键盘按键等动作

from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult')
source = browser.find_element_by_css_selector('#draggable')
target = browser.find_element_by_css_selector('#droppable')
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()

结果

python爬虫之动态渲染页面抓取-(Selenium)的使用

 

 7、执行Javascript

对于没有提供的操作,如下拉进度条,可以使用excute_script()方法实现。

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 下拉到底部后,谈出alert提示框
browser.execute_script('alert("To Bottom")') 

 8、获取节点信息

page_source 属性可以获取网页的源代码,然后通过Beautiful soup pyquery进行信息提取

也可以使用selenium自带的获取属性、文本等

· 获取属性

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_by_id('Popover1-toggle')
print(logo)
#输出class="Input"的值
print(logo.get_attribute('class'))

结果:

"f6ae22acea8757f858eb2c7939c2ee8b", element="0060864e-d6ed-4690-a481-e093da6b0254")>
Input

· 获取文本值

text()

·获取 id、位置、 标签名和大小

id 属性可以获取节点 id, location 属性可以获取该节点在页面中的相对位置, tag_name 属性可以获取标签名称, 就是宽高

9、延时等待

get()方法会在网页框架加载结束后结束执行,此时如果获取page_source,可能并不是浏览器完全加载完全的页面,如果有页面有额外的Ajax请求,在网页源代码中并不一定能成功获取,所以需要延时等待一下。

·隐式等待

from selenium import webdriver
browser = webdriver.Chrome()
# 隐式等待,默认等待0秒,找不到继续等一会在找,容易受到页面加载时间的影响
browser.implicitly_wait(10)
browser.get('https://www.zhihu.com/explore')
input = browser.find_element_by_class_name('Input')
print(input)

结果:

"318f4d1c97b1ecec3d8043cdf957e054", element="888440c5-9c7b-42d6-9be2-3bab91a59d98")>

·显式等待

指定一个最长等待时间

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)

结果:

"ac8a2a732adbaf4571fbb92e17fe5889", element="9ef29720-d902-42b6-94d4-54868739ad94")> "ac8a2a732adbaf4571fbb92e17fe5889", element="ea01d031-dc8e-4cb4-9703-fadb51ff33de")>

python爬虫之动态渲染页面抓取-(Selenium)的使用

 

 10、前进和后退 

forword() 前进下一个页面,back() 返回前一个页面

11、COOKIEs 

get_COOKIEs() 方法获取所有的 COOKIE 

add_COOKIEs() 方法添加COOKIEs

delete_all_COOKIEs()方法删除所有的 COOKIEs 

python爬虫之动态渲染页面抓取-(Selenium)的使用


推荐阅读
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
author-avatar
琼小海
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有