ajax基本介绍
selenium的背景
一、我们以前爬取的网页大多数都是一些静态的网页
1、何为静态网页?其实就是 我们像一个 网站(url)发起请求 得到响应 那么这些响应的数据都是在网页的源代码当中 解析的动作
2、除了静态网页 还有一些网页或者是网站的数据不在这个请求的url 地址当中。那么这些数据有可能是通过ajax技术加载出来的数据
二、什么是ajax技术? 前端的技术
1、 JS
js是网络上最常用的脚本语言,它可以收集用户的跟踪数据,不需要重载页面直接提交表单,在页面嵌入多媒体文件,甚至运行网
三、网页中有我们要爬取 的数据,但是网页的源码中没有,我们该如何解决?
1、要分析 真正的ajax数据接口,通过代码来请求这个接口的url从而来获取真正的数据
2、分析数据接口会比较麻烦
代码编写比较容易
3、通过selenium来模拟浏览器获取数据
通过selenium来模拟人的行为动作
代码量比较大,实现起来较为麻烦
那么这两种方式用哪一个? 1 具体情况具体分析 2 根据你自己的技术的掌握长度
一、动态了解HTML技术
1、 JS
js是网络上最常用的脚本语言,它可以收集用户的跟踪数据,不需要重载页面直接提交表单,在页面嵌入多媒体文件,甚至运行网页
2、 jQuery
jQuery是一个快速、简介的JavaScript框架,封装了JavaScript常用的功能代码
3、ajax
ajax可以使用网页实现异步更新,可以在不重新加载整个网页的情况下,对网页的某部分进行更新
获取ajax数据的方式
一、直接分析ajax调用的接口。然后通过代码请求这个接口。
1、这个方法的优点:直接可以请求到数据。不需要做一些解析工作。代码量少,性能高。
2、缺点:分析接口比较复杂,特别是一些通过js混淆的接口,要有一定的js功底。容易被发现是爬虫。
二、使用Selenium+chromedriver模拟浏览器行为获取数据
1、优点:直接模拟浏览器的行为。浏览器能请求到的,使用selenium也能请求到。爬虫更稳定。
2、缺点:代码量多。性能低
Selenium+chromedriver
一、Selenium 介绍
1、selenium是一个web的自动化测试工具,最初是为网站自动化测试而开发的,selenium可以直接运行在浏览器上,它支持所有主流的浏览器,可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏
2、chromedriver是一个驱动Chrome浏览器的驱动程序,使用他才可以驱动浏览器。当然针对不同的浏览器有不同的driver
Phantomjs快速入门
无头浏览器:一个完整的浏览器内核,包括js解析引擎,渲染引擎,请求处理等,但是不包括显示和用户交互页面的浏览器
from selenium import webdriver
import time
# 没有配置之前需要添加驱动的路径
driver = webdriver.PhantomJS()
# 驱动是添加到了 python解释器的文件夹当中了(path环境变量里面)
'''
没有配置驱动会报的错误
Message: 'phantomjs' executable needs to be in PATH.
解决 找到驱动的绝对路径
或者添加到path环境变量当中 一劳永逸(可以添加到你python解释器的文件夹当中)
'''
driver.get('https://www.baidu.com/') # 加载一个网站
# 定位输入框
driver.find_element_by_id('kw').send_keys('python')
# input_tag = driver.find_element_by_id('kw')
# input_tag.send_keys('python')
driver.find_element_by_id('su').click()
time.sleep(2)
print(driver.current_url) # 查看当前请求的url
driver.save_screenshot('baidu.png')
selenium快速入门
from selenium import webdriver
import time
driver = webdriver.Chrome()
# 加载百度
driver.get('https://www.baidu.com/')
time.sleep(2) # 停止2秒
driver.maximize_window()
time.sleep(1)
# 关闭窗口(当前窗口)
driver.close()
time.sleep(2)
# 退出驱动(关闭所有的窗口)
driver.quit()
定位元素
1、find_element_by_id:根据id来查找某个元素
2、find_element_by_class_name:根据类名查找元素
3、find_element_by_name:根据name属性的值来查找元素
4、find_element_by_xpath:根据xpath语法来获取元素
5、要注意,find_element是获取第一个满足条件的元素。find_elements是获取所有满足条件的元素。
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
'''
1、find_element_by_id:根据id来查找某个元素
2、find_element_by_class_name:根据类名查找元素
3、find_element_by_name:根据name属性的值来查找元素
4、find_element_by_xpath:根据xpath语法来获取元素
5、要注意,find_element是获取第一个满足条件的元素。find_elements是获取所有满足条件的元素。
'''
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
# 定位输入框
# find_element_by_id:根据id来查找某个元素 具体情况具体分析
# driver.find_element_by_id("kw").send_keys('python') # 第一种写法
# driver.find_element(By.ID, 'kw').send_keys('杰') # 第二种写法
# time.sleep(7) # 停滞7秒
# driver.quit() # 退出驱动(关闭所有的窗口)
# find_element_by_class_name:根据类名查找元素
# driver.find_element_by_class_name('s_ipt').send_keys('看看')
# driver.find_element(By.CLASS_NAME, 's_ipt').send_keys('空间')
# find_element_by_name:根据name属性的值来查找元素
# driver.find_element_by_name('wd').send_keys('拟议')
# driver.find_element(By.NAME, 'wd').send_keys('火锅')
# 通过标签的名字
# head = driver.find_element_by_tag_name('head')
# print(head)
# find_element_by_xpath:根据xpath语法来获取元素
# driver.find_element_by_xpath('//input[@class="s_ipt"]').send_keys('终始') # 这是自己写的
# driver.find_element_by_xpath('//*[@id="kw"]').send_keys('关闭')
#
# 要注意,find_element是获取第一个满足条件的元素。find_elements是获取所有满足条件的元素。
# inputTag = driver.find_elements_by_tag_name('input')
# print(len(inputTag), inputTag) # 结果打印出17个
inputTag = driver.find_element_by_tag_name('input')
print(inputTag) # 只有一个结果
操作表单元素
一、操作输入框:分为两步。
1、第一步:找到这个元素。
2、第二步:使用send_keys(value),将数据填充进去
二、清除输入框中的内容
1、使用clear方法可以清除输入框中的内容
三、 操作按钮
1、操作按钮有很多种方式。比如单击、右击、双击等。这里讲一个最常用的。就是点击。直接调用click函数就可以了
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
'''
输入内容 send_keys()
清空内容 clear()
点击 click()
'''
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 定位 百度一下这个按钮
# 输入内容 send_keys()
# driver.find_element_by_id('su').send_keys('健脑素') # 没有报错 因为这个是input标签可以输入所以不会报错,但是这里是一个点击用的所以不会传入
# driver.find_element_by_id('wrapper').send_keys('普通版') # 报错了 因为这个元素是不能输入内容的 div标签
# driver.find_element_by_id('wrapper') # 不要输人内容这样就不会报错了,
# 清空内容 clear()
# inputTag = driver.find_element_by_id('kw') # 定义一个变量来接收
# inputTag.send_keys('回顾')
# time.sleep(2)
# # inputTag.clear() # 清空内容
# 点击 click()
# button = driver.find_element_by_id('su')
# time.sleep(3)
# button.click()
选择select
一、导入 Select
1、select元素不能直接点击。因为点击后还需要选中元素。这时候selenium就专门为select标签提供了一个类from selenium.webdriver.support.ui import Select。将获取到的元素当成参数传到这个类中,创建这个对象。以后就可以使用这个对象进行选择了。
2、 操作select标签:定位这个select标签 以参数形式传递进去
3、以什么方式来选择
3.1、根据值来选择
3.2、根据索引来选择
4、iframe 是HTML的标签 作用:文档中的文档 所以如果有ifram标签 而这个标签里面嵌套的内容正好就有你要操纵的元素,此时此刻就需要先切换ifram
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time
driver = webdriver.Chrome()
driver.get('https://www.17sucai.com/pins/demo-show?id=5926')
# 切换iframe switch_to_frame() 过时
# driver.switch_to.frame()
# iframe 是HTML的标签 作用:文档中的文档 所以如果有iframe标签 而这个标签里面嵌套的内容正好就有你要操纵的元素,此时此刻就需要先切换ifram
# driver.switch_to_frame(driver.find_element_by_id('iframe')) # 过时但是还能用不会报错
driver.switch_to.frame(driver.find_element_by_id('iframe')) # 新的版本
# select标签
selectTag = Select(driver.find_element_by_class_name('nojs'))
'''
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".nojs"}
'''
# 选择方式
# 1 根据值来选择
# selectTag.select_by_value('JP')
# 2 根据索引来选择
# selectTag.select_by_index(2)
divTag = driver.find_element_by_id('dk_container_country-nofake')
divTag.click()
time.sleep(1)
driver.find_element_by_xpath('//*[@id="dk_container_country-nofake"]/div/ul/li[5]/a').click()
鼠标行为链
一、有时候在页面中的操作可能要有很多步,那么这时候可以使用鼠标行为链类ActionChains来完成。比如现在要将鼠标移动到某个元素上并执行点击事件
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 定位输入框
inputTag = driver.find_element_by_id('kw')
# 定位百度一下的按钮
buttonTag = driver.find_element_by_id('su')
# 实例化对象
actions = ActionChains(driver)
# 让输入框中输入内容
actions.send_keys_to_element(inputTag, '打火锅')
time.sleep(1)
# actions.click() # 点击行为不要在鼠标行为链里面出现
# buttonTag.click() #
# 把鼠标移动到搜索的按钮上
actions.move_to_element(buttonTag)
actions.click()
# 提交鼠标行为链
actions.perform()
Cookie操作
一、获取所有的cookie
cookies = driver.get_cookies()
二、根据cookie的name获取cookie
value = driver.get_cookie(name)
三、删除某个cookie
driver.delete_cookie(‘key’)
页面等待
一、现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。为了解决这个问题。所以 Selenium 提供了两种等待方式:一种是隐式等待、一种是显式等待
1、隐式等待:调用driver.implicitly_wait。那么在获取不可用的元素之前,会先等待10秒中的时间
driver.implicitly_wait(10)
2、显示等待:显示等待是表明某个条件成立后才执行获取元素的操作。也可以在等待的时候指定一个最大的时间,如果超过这个时间那么就抛出一个异常。显示等待应该使用selenium.webdriver.support.excepted_conditions期望的条件和selenium.webdriver.support.ui.webdriverwait来配合完成
from selenium import webdriver
from selenium.webdriver.support.ui import webdriverwait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Chrome()
# 隐式等待
# driver.get('https://www.baidu.com/')
# time.sleep(2) # 用time方法里面写入数字几就一定要等待几秒
# 找得到元素
# driver.implicitly_wait(1000) # 隐式等待 只要找到所对应的元素就执行不用等待里面写入的数字
# driver.find_element_by_id('kw').send_keys('金狐狸')
# 找不到元素
# driver.implicitly_wait(5) # 如果输入没有的元素那么就需要等待所传入的数字的时间然后报错
# driver.find_element_by_id('keiut').send_keys('人挤人')
# 显示等待
driver.get('https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc')
driver.implicitly_wait(3)
# 千万不要忘记click() 这一步是去掉那个提示框
driver.find_element_by_xpath('//*[@id="qd_closeDefaultWarningWindowDialog_id"]').click()
# 等待出发地加载出来
webdriverwait(driver, 1000).until(
EC.text_to_be_present_in_element_value((By.ID, 'fromStationText'), '福州')
)
# 等待目的地加载出来
webdriverwait(driver, 1000).until(
EC.text_to_be_present_in_element_value((By.ID, 'toStationText'), '广州')
)
driver.find_element_by_id('query_ticket').click()
# 按钮不能够被点击
# btn = driver.find_element_by_id('query_ticket')
# driver.execute_script('arguments[0].click()', btn)
# btn.click()
打开多窗口和切换页面
一、有时候窗口中有很多子tab页面。这时候肯定是需要进行切换的。selenium提供了一个叫做switch_to_window来进行切换,具体切换到哪个页面,可以从driver.window_handles中找到
rom 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
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# driver.get('https://www.douban.com/')
# 上面两个代码都执行的话会先打开百度然后打开豆瓣但是只有一个网页并没有多一个窗口
# 先打开百度网页然后打开一个新窗口并加载豆瓣网页
driver.execute_script('window.open("https://www.douban.com/",)')
time.sleep(1)
driver.execute_script('window.open("https://www.jd.com/")')
# driver.close()
# driver.find_element_by_id('kw').send_keys('brkalsy') #
# print(driver.current_url) # 结果为:https://www.baidu.com/ 主页面还是百度
# 切换主页面
# driver.switch_to_window(driver.window_handles[1]) # 过时的写法
driver.switch_to.window(driver.window_handles[1]) # 按下标索引值[]来切换
time.sleep(1)
print(driver.current_url) # 结果为: https://www.douban.com/ 主页面现在是豆瓣