记一次使用python的selenium库爬取动态页面内容的经历
安装与配置selenium
- 安装selenium库
pip install selenium
配置浏览器驱动(本次使用Google Chrome)
- 打开Chrome,在浏览器的地址栏,输入chrome://version/,回车后即可查看到对应版本
- 找到对应的chromedriver版本,参考版本选择 | ChromeDriver | Chrome for Developers
- 下载版本匹配的chromedriver,将其解压并置于自选路径下,将
chromedriver.exe
所在路径加入环境变量。
验证:
编写并运行以下python文件,若不报错,则基本可认定配置成功:
from selenium import webdriver
# Chrome浏览器
driver = webdriver.Chrome()
编写脚本
本次实现的是在Openstack Dashboard里寻找符合条件的镜像,并将其下载下来。镜像要求是名称以“1_”开头,且配置了qga。
脚本如下:
from selenium import webdriver
from selenium.common import ElementClickInterceptedException, TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import time
# 设置 webdriver
options = webdriver.ChromeOptions()
# options.add_argument('--headless') # 无头模式,不打开实际的浏览器窗口
options.add_argument('--ignore-certificate-errors') # 忽略证书错误
driver = webdriver.Chrome(options=options)
# OpenStack Horizon登录页面URL
login_url = "https://192.168.0.60/horizon/auth/login/"
image_url = "https://192.168.0.60/horizon/project/images/"
may_url = []
username = "your_username"
password = "your_password"
def get_images():
try:
# 打开登录页面
driver.get(login_url)
# 等待并找到用户名输入框
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.NAME, "username"))
)
# 输入用户名和密码
driver.find_element(By.NAME, "domain").send_keys("default")
driver.find_element(By.NAME, "username").send_keys(username)
driver.find_element(By.NAME, "password").send_keys(password)
# 提交表单
driver.find_element(By.XPATH, '//button[@type="submit"]').click()
# 确认登录成功,等待某个已知会出现在登录成功后的元素,例如导航栏中的一个元素
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "main_content"))
)
print("登录成功")
# 访问镜像页面
driver.get(image_url)
all_images = []
processed_image_ids = set()
while True:
# 等待页面加载,并确保特定数据行存在
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.TAG_NAME, "tbody"))
)
# 确保表格内容已加载,等待特定行内容出现
while True:
rows = driver.find_elements(By.XPATH, "//tbody/tr")
if len(rows)>=3:
break
time.sleep(1)
# 获取页面内容
soup = BeautifulSoup(driver.page_source, 'html.parser')
rows = soup.find_all('tr', class_='ng-scope')
# 处理每一行数据
for row in rows:
columns = row.find_all('td')
if len(columns) > 2: # 确保有足够的列
name_column = columns[3].find('a').text.strip().rsplit('.', 1)[0]
if name_column.startswith("1_"):
link = columns[3].find('a')['href']
may_url.append("https://192.168.0.60/horizon/" + link)
# 检查是否有下一页
try:
next_button = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH,
'//span[@ng-hide="currentPage === numPages"]/a[@ng-click="selectPage(currentPage + 1)"]'))
)
next_button.click()
except (ElementClickInterceptedException, TimeoutException) as e:
print(f"Failed to click the next button: {e}")
break
for link in may_url:
print(link)
driver.get(link)
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.TAG_NAME, "dl"))
)
details_soup = BeautifulSoup(driver.page_source, 'html.parser')
properties_div = details_soup.find_all('div', {'ng-repeat': 'prop in ctrl.image.properties'})
# 查找包含名称的元素
name_element = details_soup.find('span', class_='h1 ng-binding')
name_column = name_element.text.strip().rsplit('.', 1)[0]
has_qemu_guest_agent = False
for prop in properties_div:
dt = prop.find('dt').text.strip()
dd = prop.find('dd').text.strip()
if dt == "hw_qemu_guest_agent" and dd == "yes":
has_qemu_guest_agent = True
break
if has_qemu_guest_agent:
image_id = driver.current_url.split('/')[-1]
if image_id not in processed_image_ids:
all_images.append({'name': name_column, 'id': image_id})
processed_image_ids.add(image_id)
print(f"Name: {name_column}, ID: {image_id}")
with open("images.txt", "w") as file:
for image in all_images:
file.write(f"Name: {image['name']}, ID: {image['id']}\n")
finally:
driver.quit()
if __name__ == "__main__":
get_images()
参考资源
- Selenium安装WebDriver最新Chrome驱动(含116/117/118/119)_chromedriver 119-CSDN博客
- selenium入门超详细教程——网页自动化操作-CSDN博客
记一次使用python的selenium库爬取动态页面内容的经历的更多相关文章
- Python:利用 selenium 库抓取动态网页示例
前言 在抓取常规的静态网页时,我们直接请求对应的 url 就可以获取到完整的 HTML 页面,但是对于动态页面,网页显示的内容往往是通过 ajax 动态去生成的,所以如果是用 urllib.reque ...
- selenium+phantomjs爬取动态页面数据
1.安装selenium pip/pip3 install selenium 注意依赖关系 2.phantomjs for windows 下载地址:http://phantomjs.org/down ...
- selenium自动化测试爬取动态页面大全
目录 一:浏览器信息测试 二:查找结点 三:测试动作 四:获取节点信息 五:切换子页面Frame 六,延时请求 七:前进和后退 八:Cookies 八:选项卡处理 九:捕获异常 这里之讲解用法,安 ...
- [python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈
我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的.首先通过这篇文章,你能学到以下几点: 1.可以了解Python简单爬取图片的一些思路和方法 ...
- [python爬虫] Selenium定向爬取PubMed生物医学摘要信息
本文主要是自己的在线代码笔记.在生物医学本体Ontology构建过程中,我使用Selenium定向爬取生物医学PubMed数据库的内容. PubMed是一个免费的搜寻引擎,提供生物医学方 ...
- Python 爬虫实例(8)—— 爬取 动态页面
今天使用python 和selenium爬取动态数据,主要是通过不停的更新页面,实现数据的爬取,要爬取的数据如下图 源代码: #-*-coding:utf-8-*- import time from ...
- phantomjs+selenium实现爬取动态网址
之前使用 selenium + firefox驱动浏览器来实现爬取动态网址,但是firefox经常更新,更新后时常会导致webdriver启动不来,所以改用phantomjs+selenium来改善一 ...
- 【Python成长之路】Python爬虫 --requests库爬取网站乱码(\xe4\xb8\xb0\xe5\xa)的解决方法【华为云分享】
[写在前面] 在用requests库对自己的CSDN个人博客(https://blog.csdn.net/yuzipeng)进行爬取时,发现乱码报错(\xe4\xb8\xb0\xe5\xaf\x8c\ ...
- [python爬虫] Selenium定向爬取虎扑篮球海量精美图片
前言: 作为一名从小就看篮球的球迷,会经常逛虎扑篮球及湿乎乎等论坛,在论坛里面会存在很多精美图片,包括NBA球队.CBA明星.花边新闻.球鞋美女等等,如果一张张右键另存为的话真是手都点疼了.作为程序员 ...
- 看我怎么扒掉CSDN首页的底裤(python selenium+phantomjs爬取CSDN首页内容)
这里只是学习一下动态加载页面内容的抓取,并不适用于所有的页面. 使用到的工具就是python selenium和phantomjs,另外调试的时候还用了firefox的geckodriver.exe. ...
随机推荐
- Django——form组件的局部钩子
如果对字段的校验条件太少,不能满足我们的需求,那么,我们可以对每个字段自定义校验的内容,就可以使用局部钩子. 局部钩子的使用方法: (1)导入错误类型 ----> 我们自己定义的钩子抛出的错误也 ...
- Android 13 - Media框架(11)- MediaCodec(一)
关注公众号免费阅读全文,进入音视频开发技术分享群! MediaCodec 是 Android 平台上音视频编解码的标准接口,无论是使用软解还是硬解都要通过调用 MediaCodec来完成,是学习 An ...
- NOIP模拟90(多校23)
T1 回文 解题思路 原来 \(n^3\) 可以过 500 ... 先枚举一下路径长度,对于同一路径长度点数最多是 \(n\) 个,我们可以接着枚举从 \((n,m)\) 出发的路径长度相同的点. 然 ...
- NOIP模拟55
T1 Skip 解题思路 正解给的是线段树维护单调栈,但是我不会.. CDQ 维护斜率可做!!! 先得出一个朴素的 DP 方程:设 \(f_i\) 表示最后一场是 i 的最优解. 转移方程就是 \(f ...
- 很多人讲不明白HTTPS,但是我能
很多人讲不明白HTTPS,但是我能 今天我们用问答的形式,来彻底弄明白HTTPS的过程 下面的问题都是 小明和小丽两个人通信为例 可以把小明想象成服务端,小丽想象成客户端 1. https是做什么用的 ...
- minos 1.2 内存虚拟化——guest
首发公号:Rand_cs minos 1.2 内存虚拟化--guest 项目来自乐敏大佬:https://github.com/minosproject/minos 本文继续讲述 minos 中的内存 ...
- The solution of P3012
problem & blog 很明显是个 DP. 于是我们定义 \(dp_{i,j,k}\) 为末尾的字符的 ASCII 码为 \(i\),有 \(j\) 个大写字母,\(k\) 个小写字母. ...
- 硬件开发笔记(十七):RK3568底板电路串口、485、usb原理图详解
前言 原理图有一些常用电路. 本篇就将集中常用电路分析完,如uart口,涉及usart串口.rs485.usb口. 串口 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接 ...
- org.springframework.beans.BeanUtils属性赋值 Date类型处理转换为LocalDateTime, Date不能直接赋值给LocalDateTime
Date createTime = book.getCreateTime(); Date updateTime = book.getUpdateTime(); //属性值处理 BeanUtils.co ...
- @Async异步方法对异常的处理,从内层向外层抛出机制
@Async异步方法对异常的处理,从内层向外层抛出机制 @RequestMapping(value = "/test", method = RequestMethod.GET) p ...