爬虫--动态网站爬取selenium
phantomjs的插件下载
- https://phantomjs.org/download.html --国外镜像下载
- http://npm.taobao.org/dist/phantomjs --国内镜像下载
-
谷歌浏览器驱动下载
- http://npm.taobao.org/mirrors/chromedriver/ --下载对应的版本驱动
- #放置本解释器环境下,或者自定义路径(需要添加环境变量)
-
- 其他版本
- https://googlechromelabs.github.io/chrome-for-testing/
-
找到js和谷歌的驱动driver文件夹放置(添加环境变量)
python自动化浏览
- pip install selenium --下载第三方库
-
-
- from selenium import webdriver
- import time
-
- driver = webdriver.Chrome()
-
- #尝试请求一个网站
- driver.get('https://www.baidu.com/')
-
- #页面保存
- driver.save_screenshot('baidu.png')
- time.sleep(3)
-
- #退出驱动
- #driver.quit()
-
取消页面渲染的效果(提高运行效率)
- from selenium import webdriver
- from selenium.webdriver.chrome.options import Options
-
-
- option = Options()
- option.headless = True #配置无渲染页面
-
-
- driver = webdriver.Chrome(options=option) #实例化对象,配置无渲染页面
-
- #尝试请求一个网站
- driver.get('https://www.baidu.com/')
-
-
- #获取网站数据源码
- data = driver.page_source
- print(data)
-
selenium元素定位
- 定位一个元素 定位多个元素 含义
- find_element_by_id find_elements_by_id 通过元素id定位
- find_element_by_name find_elements_by_name 通过元素name定位
- find_element_by_xpath find_elements_by_xpath 通过xpath表达式定位
- find_element_by_link_text find_elements_by_link_tex 通过完整超链接定位
- find_element_by_partial_link_text find_elements_by_partial_link_text 通过部分链接定位
- find_element_by_tag_name find_elements_by_tag_name 通过标签定位
- find_element_by_class_name find_elements_by_class_name 通过类名进行定位
- find_elements_by_css_selector find_elements_by_css_selector 通过css选择器进行定位
-
不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较的称之为断言。通过我们获取title 、URL和text等信息进行断言。
- 属性 说明
- title 用于获得当前页面的标题
- current_url 用户获得当前页面的URL
- text 获取搜索条目的文本信息
-
实例百度搜索selenium:
- from selenium import webdriver
- import time
-
- driver = webdriver.Chrome()
- #尝试请求一个网站
- driver.get('https://www.baidu.com/')
-
- # 打印标题
- title = driver.title
- print(title)
-
- # 打印当前页面URL
- now_url = driver.current_url
- print(now_url)
-
- driver.find_element_by_id("kw").send_keys("selenium")
- time.sleep(2)
- driver.find_element_by_id("su").click()
- time.sleep(1)
-
- # 再次打印当前页面title
- title = driver.title
- print(title)
-
- # 打印当前页面URL
- now_url = driver.current_url
- print(now_url)
- time.sleep(3)
-
- # 获取结果数目
- user = driver.find_element_by_class_name('nums').text
- print(user)
-
- #关闭所有窗口
- driver.quit()
-
实例二(点击’百度’首页新闻按钮):
- from selenium import webdriver
- import time
-
- driver = webdriver.Chrome()
- #尝试请求一个网站
- driver.get('https://www.baidu.com/')
-
-
- #3.刷新浏览器
- driver.refresh()
-
- #4.设置浏览器的大小
- driver.set_window_size(1400,800)
-
- #5.设置链接内容
- element=driver.find_element_by_link_text("新闻") #点击百度首页'新闻'按钮
- element.click()
-
Selenium库下webdriver模块常用方法的使用(控制浏览器操作的一些方法)
- 方法 说明
- set_window_size() 设置浏览器的大小
- back() 控制浏览器后退
- forward() 控制浏览器前进
- refresh() 刷新当前页面
- clear() 清除文本
- send_keys (value) 模拟按键输入
- click() 单击元素
- submit() 用于提交表单
- get_attribute(name) 获取元素属性值
- is_displayed() 设置该元素是否用户可见
- size 返回元素的尺寸
- text 获取元素的文本
- page_source 网页源码
-
在 WebDriver 中, 将这些关于鼠标操作的方法封装在 ActionChains 类提供
- 方法 说明
- ActionChains(driver) 构造ActionChains对象
- context_click() 执行鼠标悬停操作
- move_to_element(above) 右击
- double_click() 双击
- drag_and_drop() 拖动
- move_to_element(above) 执行鼠标悬停操作
- context_click() 用于模拟鼠标右键操作, 在调用时需要指定元素定位
- perform() 执行所有 ActionChains 中存储的行为,可以理解成是对整个操作的提交动作
-
Selenium中的Key模块为我们提供了模拟键盘按键的方法,那就是send_keys()方法。它不仅可以模拟键盘输入,也可以模拟键盘的操作。
常用的键盘操作如下:
- 模拟键盘按键 说明
- send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
- send_keys(Keys.SPACE) 空格键(Space)
- send_keys(Keys.TAB) 制表键(Tab)
- send_keys(Keys.ESCAPE) 回退键(Esc)
- send_keys(Keys.ENTER) 回车键(Enter)
-
组合键的使用
- 模拟键盘按键 说明
- send_keys(Keys.CONTROL,‘a’) 全选(Ctrl+A)
- send_keys(Keys.CONTROL,‘c’) 复制(Ctrl+C)
- send_keys(Keys.CONTROL,‘x’) 剪切(Ctrl+X)
- send_keys(Keys.CONTROL,‘v’) 粘贴(Ctrl+V)
- send_keys(Keys.F1…Fn) 键盘 F1…Fn
-
多表单切换
在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位。这时就需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面中。
- 方法 说明
- switch_to.frame() 将当前定位的主体切换为frame/iframe表单的内嵌页面中
- switch_to.default_content() 跳回最外层的页面
-
多窗口切换
在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作。WebDriver提供了switch_to.window()方法,可以实现在不同的窗口之间切换。
- 方法 说明
- current_window_handle 获得当前窗口句柄
- window_handles 返回所有窗口的句柄到当前会话
- switch_to.window() 用于切换到相应的窗口,与上一节的switch_to.frame()类似,前者用于不同窗口的切换,后者用于不同表单之间的切换。
-
cookie操作
有时候我们需要验证浏览器中cookie是否正确,因为基于真实cookie的测试是无法通过白盒和集成测试进行的。WebDriver提供了操作Cookie的相关方法,可以读取、添加和删除cookie信息。
- 方法 说明
- get_cookies() 获得所有cookie信息
- get_cookie(name) 返回字典的key为“name”的cookie信息
- add_cookie(cookie_dict) 添加cookie。“cookie_dict”指字典对象,必须有name 和value 值
- delete_cookie(name,optionsString) 删除cookie信息。“name”是要删除的cookie的名称,“optionsString”是该cookie的选项,目前支持的选项包括“路径”,“域”
- delete_all_cookies() 删除所有cookie信息
-
窗口截图
- get_screenshot_as_file(self, filename) 用于截取当前窗口,并把图片保存到本地
-
关闭浏览器
- 方法 说明
- close() 关闭单个窗口
- quit() 关闭所有窗口
-
实例一:
- from selenium import webdriver
- from time import sleep
-
- driver=webdriver.Firefox(executable_path ="F:\GeckoDriver\geckodriver")
- driver.set_window_size(400,400)
- driver.get("https://www.baidu.com")
-
- #2.搜索
- # driver.find_element_by_id("kw").send_keys("selenium")
- # driver.find_element_by_id("su").click()
-
- #3.休眠2s目的是获得服务器的响应内容,如果不使用休眠可能报错
- sleep(10)
-
-
- #4 滚动左右滚动条---向右
- js2 = "var q=document.documentElement.scrollLeft=10000"
- driver.execute_script(js2)
- sleep(15)
-
- #5 滚动左右滚动条---向左
- js3 = "var q=document.documentElement.scrollLeft=0"
- driver.execute_script(js3)
- sleep(15)
-
- #6 拖动到滚动条底部---向下
- js = "var q=document.documentElement.scrollTop=10000"
- driver.execute_script(js)
- sleep(15)
-
- #7 拖动到滚动条底部---向上
- js = "var q=document.documentElement.scrollTop=0"
- driver.execute_script(js)
- sleep(15)
-
- driver.close()
-
实例二:
- from selenium import webdriver
- import time
- dr = webdriver.Chrome()
-
- dr.get('https://tieba.baidu.com/')
- print(dr.title)
- print(dr.current_url)
-
- dr.set_window_size(1500,810)
- dr.find_element_by_xpath('//*[@id="wd1"]').send_keys('特拉普想当12年')
- dr.find_element_by_xpath('//*[@id="tb_header_search_form"]/span[1]/a').click()
- time.sleep(1)
- dr.refresh()
- time.sleep(1)
-
- #window.scrollTo() 一次性到达指定位置
- #window.scrollBy() 在现在滚动条的位置上在行增加一次
- for _ in range(200):
- dr.execute_script('window.scrollBy(0,20)')
- time.sleep(1)
-
实例3:
- from selenium import webdriver
- import time
-
- driver = webdriver.Chrome()
- url = 'https://tieba.baidu.com/'
-
- print('-------请输入贴吧账号与密码----------')
- username = input('username:').strip()
- password = input('password:').strip()
-
-
- def request(*,url):
- driver.get(url=url)
- driver.set_window_size(1300,800)
- time.sleep(2)
- driver.refresh()
- print(f'当前窗口句柄:{driver.current_window_handle}')
- print(f'当前URL:{driver.current_url}')
- print(f'当前请求窗口标题:{driver.title}')
- print('准备搜索"中级工程师')
- driver.find_element_by_xpath('//*[@id="wd1"]').send_keys('中级工程师')
- time.sleep(1)
- print('开始搜索')
- driver.find_element_by_xpath('//*[@id="tb_header_search_form"]/span[1]/a').click()
- time.sleep(2)
- print('-' * 60)
- print(f'当前窗口句柄:{driver.current_window_handle}')
- print(f'当前请求的URL:{driver.current_url}')
- print(f'-' * 60)
- driver.refresh()
- time.sleep(2)
- for _ in range(16):
- driver.execute_script('window.scrollBy(0,500)')
- time.sleep(0.5)
- print(f'正在下滑滚动条{_}次...')
- print('已经滑动至最底端...')
- print('-' * 60)
- input_content()
- time.sleep(2)
- print('内容输入完毕!')
- print('-' * 60)
- driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_12__footerULoginBtn"]').click()
- print('开始登陆')
- print(f'准备输入的账号:{username},准备输入的密码:{password}')
- print('-' * 60)
- driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_12__userName"]').send_keys(username)
- time.sleep(1)
- driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_12__password"]').send_keys(password)
- print('账号密码输入完成!准备登陆...')
- time.sleep(1)
- driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_12__submit"]').click()
- print(f'当前URL:{driver.current_url}')
- print(f'手动过验证码')
- time.sleep(15)
- input_content()
- print('内容发表成功,5/s后即将退出浏览器')
- time.sleep(10)
- driver.quit()
-
- def input_content():
- driver.find_element_by_xpath('//*[@id="tb_rich_poster"]/div[3]/div[1]/div[2]/input').send_keys('华诺德')
- driver.find_element_by_xpath('//*[@id="ueditor_replace"]/p').send_keys('https://www.sxhndjy.cn')
- driver.find_element_by_xpath('//*[@id="tb_rich_poster"]/div[3]/div[5]/div/button[1]').click()
-
-
- if __name__ == '__main__':
- request(url=url)
-
- options = webdriver.ChromeOptions()
- # 以最高权限运行
- options.add_argument('--no-sandbox')
- # options.add_argument('--proxy-server=socks5://127.0.0.1:1080')
- # 禁用浏览器提示正在受自动化软件控制
- options.add_experimental_option('useAutomationExtension', False)
- # 防止反爬
- options.add_experimental_option('excludeSwitches', ['enable-automation'])
- # 指定用户文件夹User Data路径,可以把书签这样的用户数据保存在系统分区以外的分区
- options.add_argument('--user-data-dir=E:\\code\\tw\\tt\\cache')
- # 指定缓存Cache路径
- options.add_argument('--disk-cache-dir=E:\\code\\tw\\tt\\cache')
- # 谷歌文档提到需要加上这个属性来规避bug
- options.add_argument('--disable-gpu')
- # 禁用浏览器弹窗
- prefs = {
- 'profile.default_content_setting_values': {
- 'notifications': 2
- }
- }
-
配置参数
每次当selenium启动chrome浏览器的时候,chrome浏览器很干净,没有插件、没有收藏、没有历史记录,这是因为selenium在启动chrome时为了保证最快的运行效率,启动了一个裸浏览器,这就是为什么需要配置参数的原因,但是有些时候我们需要的不仅是一个裸浏览器
selenium启动配置参数接收是ChromeOptions类,创建方式如下 :
- from selenium import webdriver
- option = webdriver.ChromeOptions()
- driver = webdriver.Chrome(chrome_options=option)
-
创建了ChromeOptions类之后就是添加参数,添加参数有几个特定的方法,分别对应添加不同类型的配置项目
- from selenium import webdriver
- option = webdriver.ChromeOptions()
-
- # 添加启动参数
- option.add_argument()
-
- # 添加扩展应用
- option.add_extension()
- option.add_encoded_extension()
-
- # 添加实验性质的设置参数
- option.add_experimental_option()
-
- # 设置调试器地址
- option.debugger_address()
-
常用配置参数
- from selenium import webdriver
- option = webdriver.ChromeOptions()
-
- # 添加UA
- options.add_argument('user-agent="MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"')
-
- # 指定浏览器分辨率
- options.add_argument('window-size=1920x3000')
-
- # 谷歌文档提到需要加上这个属性来规避bug
- chrome_options.add_argument('--disable-gpu')
-
- # 隐藏滚动条, 应对一些特殊页面
- options.add_argument('--hide-scrollbars')
-
- # 不加载图片, 提升速度
- options.add_argument('blink-settings=imagesEnabled=false')
-
- # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
- options.add_argument('--headless')
-
- # 以最高权限运行
- options.add_argument('--no-sandbox')
-
- # 手动指定使用的浏览器位置
- options.binary_location = r"C:Program Files (x86)GoogleChromeApplicationchrome.exe"
-
- #添加crx插件
- option.add_extension('d:crxAdBlock_v2.17.crx')
-
- # 禁用JavaScript
- option.add_argument("--disable-javascript")
-
- # 设置开发者模式启动,该模式下webdriver属性为正常值
- options.add_experimental_option('excludeSwitches', ['enable-automation'])
-
- # 禁用浏览器弹窗
- prefs = {
- 'profile.default_content_setting_values' : {
- 'notifications' : 2
- }
- }
- options.add_experimental_option('prefs',prefs)
-
- # 添加代理 ip
- options.add_argument("--proxy-server=http://XXXXX.com:80")
-
- driver = webdriver.Chrome(chrome_options=chrome_options)
-
其他配置项目参数
- --user-data-dir=[PATH]
- # 指定用户文件夹User Data路径,可以把书签这样的用户数据保存在系统分区以外的分区
-
-
- –disk-cache-dir=[PATH]
- # 指定缓存Cache路径
-
- –disk-cache-size=
- # 指定Cache大小,单位Byte
-
- –first run
- # 重置到初始状态,第一次运行
-
- –incognito
- # 隐身模式启动
-
- –disable-javascript
- # 禁用Javascript
-
- --omnibox-popup-count="num"
- # 将地址栏弹出的提示菜单数量改为num个
-
- --user-agent="xxxxxxxx"
- # 修改HTTP请求头部的Agent字符串,可以通过about:version页面查看修改效果
-
- --disable-plugins
- # 禁止加载所有插件,可以增加速度。可以通过about:plugins页面查看效果
-
- --disable-javascript
- # 禁用JavaScript,如果觉得速度慢在加上这个
-
- --disable-java
- # 禁用java
-
- --start-maximized
- # 启动就最大化
-
- --no-sandbox
- # 取消沙盒模式
-
- --single-process
- # 单进程运行
-
- --process-per-tab
- # 每个标签使用单独进程
-
- --process-per-site
- # 每个站点使用单独进程
-
- --in-process-plugins
- # 插件不启用单独进程
-
- --disable-popup-blocking
- # 禁用弹出拦截
-
- --disable-plugins
- # 禁用插件
-
- --disable-images
- # 禁用图像
-
- --incognito
- # 启动进入隐身模式
-
- --enable-udd-profiles
- # 启用账户切换菜单
-
- --proxy-pac-url
- # 使用pac代理 [via 1/2]
-
- --lang=zh-CN
- # 设置语言为简体中文
-
- --disk-cache-dir
- # 自定义缓存目录
-
- --disk-cache-size
- # 自定义缓存最大值(单位byte)
-
- --media-cache-size
- # 自定义多媒体缓存最大值(单位byte)
-
- --bookmark-menu
- # 在工具 栏增加一个书签按钮
-
- --enable-sync
- # 启用书签同步
-