爬虫动态渲染页面爬取之selenium驱动chrome浏览器的使用
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样,可以用其进行网页动态渲染页面的爬取。
支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。
1. 示例
### selenium的使用
'''
Selenium是一个用于Web应用程序测试的工具。
Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。
''' ## 示例
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')
input = browser.find_element_by_id('kw')
input.send_keys('Python')
input.send_keys(Keys.ENTER)
wait = WebDriverWait(browser, 10)
wait.until(ec.presence_of_element_located((By.ID, 'content_left')))
print(browser.page_source)
print(browser.current_url)
print(browser.get_cookies())
finally:
browser.close()
2. 声明浏览器对象
## 声明浏览器对象
from selenium import webdriver # 声明1个chrome浏览器对象
browser1 = webdriver.Chrome()
# 声明1个firefox浏览器对象
browser2 = webdriver.Firefox()
# 声明1个edge浏览器对象
browser3 = webdriver.Edge()
# 声明1个safari浏览器对象
browser4 = webdriver.Safari()
# 声明1个phantonjs无界面浏览器对象
browser5 = webdriver.PhantomJS()
3. get方法访问页面
## 访问页面,get方法
from selenium import webdriver # 声明浏览器对象
browser = webdriver.Chrome()
# 访问淘宝主页
browser.get('https://www.taobao.com')
# 打印访问到的页面源码
print(browser.page_source)
# 关闭浏览器
browser.close()
4. 查找节点
## 查找节点
## element返回单个节点对象,
## elements返回多个节点对象的列表
# 1.根据id、class、name、text、tag等的值获取:find_element_by_id,
# 2.通过css选择器获取:find_element_by_css_selector
# 3.通过xpath方法获取:find_element_by_xpath
from selenium import webdriver
from selenium.webdriver.common.by import By browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input_1 = browser.find_element_by_id('q')
input_2 = browser.find_element_by_css_selector('#q')
input_3 = browser.find_element_by_xpath('//input[@id="q"]')
# 查找节点的其他写法
input_other = browser.find_element(By.CSS_SELECTOR, '#q')
# 查找多个节点,返回匹配到的对象的列表
elements = browser.find_elements(By.XPATH, '//*[contains(@class, "service-bd")]//li') print(type(elements), elements)
print(input_1, input_2, input_3, input_other)
print(type(input_1), type(input_2), type(input_3), type(input_other))
browser.close()
5. 节点间进行交互
## 节点交互
## 输入内容send_keys
## 清空内容clear
## 触发点击click
import time
from selenium import webdriver browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input = browser.find_element_by_id('q')
input.send_keys('电脑')
time.sleep(2)
input.clear()
input.send_keys('手机')
button = browser.find_element_by_xpath('//button[contains(@class, "btn-search")]')
button.click()
time.sleep(2) browser.close()
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)
# webDriver只能在一个页面上对元素识别和定位,对于frame/iframe表单内嵌页面上的元素无法直接定位,
# 此时就需要通过switch_to.frame()方法将当前定位的主题切换为iframe表单的内嵌页面中。
browser.switch_to.frame('iframeResult')
drag = browser.find_element_by_id('draggable')
drop = browser.find_element_by_id('droppable')
# 声明对象
action = ActionChains(browser)
# 调用drag_and_drop方法
action.drag_and_drop(drag, drop)
# 执行刚刚调用的方法
action.perform()
browser.close()
7. 执行JavaScript
## 执行JavaScript
from selenium import webdriver browser = webdriver.Chrome()
browser.get('https://www.mi.com/')
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("已到底部")')
8. 获取节点信息,如text,attribute等
## 获取节点信息
from selenium import webdriver browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
s = browser.find_element_by_id('tb-beacon-aplus')
print(type(s), s)
# 获取s节点的src属性信息
print(s.get_attribute('src')) s2 = browser.find_element_by_class_name('site-nav-menu-hd')
# 获取节点的文本信息
print(s2.text)
# 获取节点的id
print(s2.id)
# 获取节点的标签名
print(s2.tag_name)
# 获取节点基于页面的相对位置
print(s2.location)
# 获取节点内容的大小,即占据页面的长度以及宽度
print(s2.size) browser.close()
9. 切换Frame
## 切换Frame
# 网页中有一种iframe节点,iframe节点里的内容相当于页面的子页面,子页面内容结构和正常网页结构完全一致
# selenium打开页面时只能获取到父级Frame页面的内容,要想获取子页面内容,需要switch_to.frame()方法来切换页面
from selenium import webdriver
from selenium.common import exceptions browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
try:
browser.find_element_by_id('droppable')
except exceptions.NoSuchElementException:
print('NO element...')
# 切换frame
browser.switch_to.frame('iframeResult')
s = browser.find_element_by_id('droppable')
print(s)
10. 延时等待
## 延时等待
## 隐式等待,类似于time.sleep
## 显式等待,当检测到某个节点内容后即返回,推荐使用
# 隐式等待
from selenium import webdriver browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get('https://www.taobao.com')
input = browser.find_element_by_id('q')
print(input.tag_name) browser.close() # 显式等待
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')
# 基于browser构建一个等待对象,等待最大时间为10s
wait = WebDriverWait(browser, 10)
# 等待10s时间内,如果页面出现id="q"节点时,则返回节点并且程序继续执行,否则抛出异常,程序结束
# presence_of_element_located中进行判断节点是否出现,传入一个元组
w = wait.until(EC.presence_of_element_located((By.ID, 'q')))
input = browser.find_element_by_id('q')
print(w.id, input.tag_name) browser.close() '''
其他等待条件说明:
title_is 标题是某内容
title_contains 标题包含某内容
presence_of_element_located 节点加载出来(传入元组(By.ID, 'q'))
visibility_of_element_located 节点可见,传入定位元组
visibility_of 节点对象可见,传入节点对象
presence_of_all_elements_located 所有节点加载出来
text_to_be_present_in_element 某个节点文本包含某文字
text_to_be_present_in_element_value 某个节点值包含某文字
text_to_be_available_amd_switch_to_it 加载并切换
invisibility_of_element_located 节点不可见
element_to_be_clickable 节点可点击
staleness_of 判断节点是否在DOM,可用于判断页面是否已经刷新
element_to_be_selected 节点可选择,传入节点对象
element_located_to_be_selected 节点可选择,传入节点定位元组
element_selection_state_to_be 传入节点对象及状态,相等返回True
element_located_selection_state_to_be 传入定位元组及状态,相等返回True
alert_is_present 是否出现警告
'''
11. 前进和后退
## 前进和后退
from selenium import webdriver
import time browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.get('https://www.taobao.com')
browser.get('https://www.zhihu.com')
browser.get('https://www.mi.com')
browser.back()
browser.back()
browser.forward()
time.sleep(2) browser.close()
12. Cookies操作,获取、添加、删除等
## Cookies操作,获取、添加、删除
from selenium import webdriver browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print(len(browser.get_cookies()), browser.get_cookies())
browser.add_cookie({'name': 'name', 'domain': '.taobao.com', 'value': 'dfjld'})
print(len(browser.get_cookies()), browser.get_cookies())
browser.delete_all_cookies()
print(len(browser.get_cookies()), browser.get_cookies()) browser.close()
13. 选项卡操作
## 选项卡处理
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])
browser.get('https://www.taobao.com')
print(browser.current_url)
browser.switch_to.window(browser.window_handles[0])
print(browser.current_url) browser.close()
14. 异常处理
## 异常处理
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, TimeoutException browser = webdriver.Chrome()
try:
browser.get('https://www.taobao.com')
except TimeoutException:
print('TIME OUT...') try:
browser.find_element_by_id('qdfd')
except NoSuchElementException:
print('NO ELEMENT...') finally:
browser.close()
15. selenium爬取jd商品信息实例代码
### selenium爬取jd商品信息
### Author: dmr
from pyquery import PyQuery as pq
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import StaleElementReferenceException
from urllib.parse import quote
import requests, time, pymongo def get_source_page(browser, keyword, page):
'''
判断当前页面是否加载完成并返回加载完成页面源码
:param page:页码
:return:页面源码
''' wait = WebDriverWait(browser, 10)
print('正在爬取第 %d 页' % page)
try:
url = 'https://search.jd.com/Search?enc=utf-8&keyword=' + quote(keyword)
browser.get(url)
# 拉到浏览器页面底部,获取当前页面所有的商品信息,防止操作过程中页面节点变化导致操作失败
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
time.sleep(2)
# wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#J_goodsList li.gl-item > div.gl-i-wrap')))
# 当page大于1时,进行页面跳转
if page > 1:
# 获取当前跳转页面节点
page_input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#J_bottomPage .p-skip > input')))
# 获取跳转页面按键节点
submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_bottomPage .p-skip > a')))
page_input.clear()
page_input.send_keys(str(page))
submit.click()
# 确保已完成页面跳转
wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#J_bottomPage .p-num > a.curr'), str(page)))
# 确保页面商品信息加载完成
wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#J_goodsList li.gl-item > div.gl-i-wrap')))
print('第 %s 页面加载完成,可以进行获取源码...' % str(page)) return browser.page_source except TimeoutException or StaleElementReferenceException:
# 如果出现错误,继续尝试爬取
print('出现错误,正在继续尝试。。。')
get_source_page(browser, keyword, page) def get_data(html):
'''
提取网页源代码并进行解析获取想要爬取的内容
:return:
''' doc = pq(html)
items = doc('#J_goodsList li > .gl-i-wrap').items()
for item in items:
yield {
'img': item('.p-img img').attr.src if item('.p-img img').attr.src else item('.p-img img').attr('data-lazy-img'),
'price': item('.p-price strong i').text(),
'title': item('.p-name.p-name-type-2 em').text(),
'commit': item('.p-commit strong a').text(),
'shop': item('.p-shop span a').text(),
'icons': item('.p-icons i').text(),
} def save_to_mongodb(collection, data):
for item in data:
try:
collection.insert_one(item)
print("插入数据成功,数据内容为:", item)
except:
print("插入数据内容失败,数据内容为:", item) def main(browser, keyword, offset):
html = get_source_page(browser, keyword, offset)
if html:
data = get_data(html)
# 建立连接对象
client = pymongo.MongoClient(host='10.0.0.100', port=27017)
# 指定数据库,如无则创建
db = client.jd
# 指定集合,如无则创建
collection = db[keyword]
# 保存到mongodb中
save_to_mongodb(collection, data)
else:
print('第%s页的页面源码加载有误,页面源码为:%s' % (offset, html)) if __name__ == '__main__':
keyword = input("请输入商品信息关键字:")
browser = webdriver.Chrome()
for page in range(1, 101):
main(browser, keyword, page) browser.close()
更多用法参见官方:http://selenium-python.readthedocs.io/api.html
爬虫动态渲染页面爬取之selenium驱动chrome浏览器的使用的更多相关文章
- 爬虫动态渲染页面爬取之Splash的介绍和使用
Splash是一个JavaScript渲染服务,是一个带有HTTP API的轻量级浏览器,同时它对接了Python中的Twisted和QT库.利用它,我们同样可以实现动态渲染页面的抓取. 1. 功能介 ...
- 动态渲染页面爬取(Python 网络爬虫) ---Selenium的使用
Selenium 的使用 Selenium 是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击.下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬.对于一些JavaS ...
- 动态渲染页面爬取-Selenium & Splash
模拟浏览器的动机 JS动态渲染的页面不止Ajax一种 很多网页的Ajax接口含有加密参数,分析其规律的成本过高 通过对浏览器运行方式的模拟,我们将做到:可见即可爬 Python中常用的模拟浏览器运行的 ...
- 爬虫之Selenium 动态渲染页面爬取
Selenim 是一个自动化测试工具,可以利用它驱动浏览器执行特定的动作,如点击.下拉等操作,同时可以获取浏览器当前呈现的页面的源代码,做到可见及可爬 1.使用流程 1)声明浏览器对象 Seleniu ...
- python3编写网络爬虫14-动态渲染页面爬取
一.动态渲染页面爬取 上节课我们了解了Ajax分析和抓取方式,这其实也是JavaScript动态渲染页面的一种情形,通过直接分析Ajax,借助requests和urllib实现数据爬取 但是javaS ...
- selenium驱动chrome浏览器问题
selenium是一个浏览器自动化测试框架,以下介绍其如何驱动chrome浏览器? 1.下载与本地chrome版本对应的chromedriver.exe ,下载地址为http://npm.taobao ...
- [Python3网络爬虫开发实战] 7-动态渲染页面爬取
在前一章中,我们了解了Ajax的分析和抓取方式,这其实也是JavaScript动态渲染的页面的一种情形,通过直接分析Ajax,我们仍然可以借助requests或urllib来实现数据爬取. 不过Jav ...
- python爬虫10 b站爬取使用 selenium+ phantomJS
但有时候 我们不想要让它打开浏览器去执行 能不能直接在代码里面运行呢 也就是说 有没有一个无形的浏览器呢 恩 phantomJS 就是 它是一个基于 WebKit 的浏览器引擎 可以做到无声无息的操作 ...
- (原创)如何使用selenium 驱动chrome浏览器并且打开方式为手机模式-转载请注明出处
随着移动设备使用率的不断增加,移动页面的测试也变得越来越重要. 对于互联网公司M站的测试,如果不通过专用的appium等移动端测试工具是否还有方便快捷的办法呢?答案当然是有啊. 使用chrome dr ...
随机推荐
- UltraSoft - Alpha - Scrum Meeting 2
Date: Apr 09th, 2020. 会议内容为完成初步的任务分工. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM.后端 继续Django tuto ...
- PromQL的简单使用
PromQL的简单使用 一.背景 二.PromQL的数据类型 三.字面量 1.字符串字面量 2.浮点数字面量 四.时间序列选择器 1.即时向量选择器 1.组成部分 2.指标名称和匹配器的组合 3.匹配 ...
- Noip模拟50 2021.9.10
已经好长时间没有考试不挂分的良好体验了... T1 第零题 开场数据结构,真爽 对于这道题首先要理解对于一条链从上向下和从下向上走复活次数相等 (这可能需要晚上躺在被窝里面脑摸几种情况的样例) 然后就 ...
- hdu 1080 Human Gene Functions(DP)
题意: 人类基因由A.C.G.T组成. 有一张5*5的基因表.每格有一个值,叫相似度.例:A-C:-3.意思是如果A和C配对, 则它俩的相似度是-3[P.S.:-和-没有相似度,即-和-不能配对] 现 ...
- Centos7上安装Ubuntu容器
1.再次之前我们要先装好docker,在上一篇我已经给出了教程,没有安装好的快去看看吧! 2.这里我们使用的是linux系统,所有在线安装是最简便的方法了.我们可以从国内拉取dockerhub镜像,这 ...
- java+selenium+testNG+Allure报表【新增截图到报表功能】
1.pom.xml配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://w ...
- idea Mark Directory as 的几种文件类型
1. Source roots (or source folders) 源文件夹 通过为该类别分配文件夹,可以告诉IntelliJ IDEA该文件夹及其子文件夹包含应在构建过程中进行编译的源代码. 2 ...
- 实验8:数据平面可编程实践——P4
一.实验目的 掌握V1Model框架下P4_16的程序结构和基本语法 能够运用 P4 进行简单数据平面编程 二.实验报告 在修改basic_tunnel.p4的内容之后输入make run 验证创建结 ...
- Django 小实例S1 简易学生选课管理系统 11 学生课程业务实现
Django 小实例S1 简易学生选课管理系统 第11节--学生课程业务实现 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 课程模块中,学生需要拥 ...
- SQL Server2019数据库备份与还原脚本,数据库可批量备份
前言 最近公司服务器到期,需要进行数据迁移,而数据库属于多而繁琐,通过图形化界面一个一个备份所需时间成本很大,所以想着写一个sql脚本来执行. 开始 数据库单个备份 数据库批量备份 数据库还原 数据库 ...