5.11ajax介绍和爬取ajax数据的两种方式
ajax:Asynchronous JavsScript And XML,异步JavaScript和XML,浏览器与服后台通过XML交换少量数据,通过JS渲染页面。
【目前已经改成JSON交换数据】
ajax特点:页面加载其他数据时不需要重新请求页面的URL;ajax加载的数据,通过Chrome在网页源码中看不到。而在Selenium中driver.page_source是可以看到的!!!
获取ajax数据的方式:
1.分析接口:分析请求数据的接口,直接构造Requetst请求数据;
2.selenium:模拟浏览器行为;
5.12selenium+chromedriver安装和入门
1.selenium相当于机器人,模拟人类在浏览器上的行为;chromedriver是chrome浏览器的驱动程序,不同浏览器有不同的驱动程序。
2.安装selenium、chromedrive
3.测试selenium+chromedriver
from selenium import webdriver
driver_path=r"D:\ProgramApp\chromedriver\chromedriver.exe"
driver=webdriver.Chrome(executable_path=driver_path)
driver.get('https://www.baidu.com')
print(driver.page_source)
5.13关闭页面和浏览器
1.关闭页面
关闭标签页:driver.close()
关闭浏览器:driver.quit()
5.13定位元素
1.获取一个元素
#1.根据id
inputTag=driver.find_element_by_id('kw')
#2.根据类名
inputTag=driver.find_element_by_class_name('s_ipt')
#3.根据name属性
inputTag=driver.find_element_by_name('wd')
#4.根据标签名
inputTag=driver.find_element_by_tag_name('input')
#5.根据xpath语法
inputTag=driver.find_element_by_xpath("//input[@id='kw']")
#6.根据css选择器
inputTag=driver.find_element_by_css_selector('.s_ipt')
2.获取多个元素
方法通获取一个元素,API名变为:
driver.find_elements_by_id()
其他选择方式同理
3.API的另一种写法:
from selenium.webdriver.common.by import By
driver.find_element_by_id(‘kw’)
driver.find_element(By.id,'kw')
两种作用相同,其他选择方式同理
【注意:
如果只是想解析网页中的数据,推荐将网页源代码driver.page_source传给lxml来解析查找元素,因为lxml底层为C语言,执行效率更高;如果是想要对元素进行一些操作,比如给文本框输入值,或点击某个按钮,就必须使用selenium中提供的查找元素的方法。
强调:selenium的driver.page_source返回源码中包含通过ajax加载出的元素,是真正的源码
】
5.15操作表单元素
1.常见表单元素
输入框:input type=‘text/password/email/number’
按钮:button、input type=‘submit’
勾选框:input type=‘checkbox’
下拉列表:select
1)操作输入框
send_keys(value):用value填充输入框
clear():清除输入框数据
inputTag=driver.find_element_by_id('kw')
inputTag.send_keys('python')
inputTag.clear()
2)操作勾选框
click()
rememberBox=driver.find_element_by_name('remember')
rememberBox.click()
点一次选中,点两次取消选中
3)操作下拉列表
根据索引选择:select_by_index()
根据value属性选择:select_by_value()
根据可见文本选中:select_by_visible_text()
取消选中:deselect_all()
from selenium.webdriver.ui import Select
selectList=Select(driver.find_element_by_name('jumpMenu'))
selectList.select_by_index(1)
selectList.select_by_value('abc')
selectList.select_by_visible_text('this is a text')
selectList.deselect_all()
索引从1算起,
4)按钮点击事件
submitBtn=driver_find_element_by_id('su')
submitBtn.click()
5.16selenium行为链
行为链ActionChains:在页面中某个操作分很多步,可使用鼠标行为链类ActionChains,该类主要应用在自动化测试中在爬虫中使用不多
from selenium.webdriver.common.action_chains import ActionChains
actions=ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
action.move_to_element(submintBtn)
actions.click(submitBtn)
actions.perform()
5.17selenium操作cookie
1.获取该域名下所有的driver.get_cookies()
2.根据cookie的name获取value:get_cookie(name)
3.删除所有的cookie:delete_all_cookies()
4.删除某个cookie:delete_cookie(name)
注意:
看cookie的结构可知,每个cookie有一个name和一个值
driver.get_cookies()
driver.get_cookie("PSTM")
driver.delete_cookie("PSTM")
driver.delete_all_cookies()
5.18selenium的隐式等待和显示等待
网页采用Ajax技术,元素加载时不会瞬间加载完成,当元素还没加载出来就对该元素进行操作会导致NullPointer异常,为此,selenium提供两种方法等元素加载出来后再操作:隐式等待、显式等待
隐式等待:当获取的元素不存在时,等待固定时长,不管中途元素是否出现,固定时长后才进行获取元素操作,若还不存在则抛出异常
显示等待:当获取的元素不存在时,等待到某条件成立后就可执行获取元素操作,同时还存在一个最长等待时间,若还不存在则抛出异常
#隐式等待
driver.implicitly_wait(20)
#显式等待
from selenium.webdriver.support import expected_condiction as EC
from selenium.webdriver.common.by import By
WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,'kw'))
)
【注意:
1)显式等待,until中By和By的值必须以元组的方式传入
2)显式等待,By.xpath中只能查找元素而不能查找元素的text(),不然会超时
】
5.19selenium打开多窗口(标签页)和切换窗口
1.打开多窗口
1)使用JS代码打开多窗口
2)再selenium中执行JS代码
driver.execute_script("window.open('https://www.douban.com')")
url="https://www.douban.com"
driver.execute_script("window.open(%s)"%url)
【注意:
打开第二个窗口后,selenium中焦点还停在第一个界面,若想操作的第二个窗口,要先切换到第二个窗口上
driver.current_url()、driver.page_source()都对应的是当前打开窗口
另外,如果直接使用driver.get(new_url)的化,并不会打开多个标签页,而是new_url标签页覆盖掉原来的第一个标签页
】
2.切换窗口
1)获取窗口句柄,window_handles中按打开顺序存有所有窗口的句柄
2)切换到指定窗口
driver.switch_to_window(driver.window_handles[1])
5.20selenium使用代理IP
options=webdriver.ChromOptions()
options.add_argument("--proxy-server=http://110.73.2.248:8123")
driver_path=r"D:\ProgramApp\chromedriver\chromedriver.exe"
driver=webdriver.Chrome(executable_path=driver_path,chrome_options=options)
driver.get('http://httpbin.org/ip')
【注意:
http://httpbin.org/
整个网站可以测试Request、Response;查看当前访问时的IP
】
5.21selenium中的WebElement类补充
webdriver.Chrome()返回的driver,继承自WebElement类;driver中find_element查找元素返回的元素的类型也为WebElement
获取属性:get_attribute、get_property
get_property:查找的是HTML中原生的属性
get_attribute:首先调用get_property,若找不到会用其它方法找;
获取属性建议使用get_attribute方法
5.22selenium完美实现拉勾网列表之爬虫解析
1.分析接口方式爬取ajax数据
1)chrome-F12-Network中找到发送的ajax请求,分析请求参数,请求方式
2)构造请求头,最保险的方式是直接把Chrome中请求头全复制过来;常见的反爬虫参数:IP、Referer、Origin、Cookie
【注意:这个反爬虫,不是找不到请求的URL、也不是请求头中某个参数进行了加密无法获取,而是要解决请求中包含了哪些字段,还有其他未知因素】
【在遭到反爬虫时,改用浏览器访问,可能可以在请求头中看到X-Anti-…字段,表明遭到反爬虫】
也就是说,在被反爬虫时,甚至很难确定服务器通过什么方式判断为爬虫的
5.23selenium完美实现拉勾网详情页之爬虫解析
请求头中的cookie,很可能被反爬虫
5.24selenium完美实现拉勾网爬虫之跑通流程
略
补充:
1.selenium静默方式执行(不显示浏览器界面)
option = webdriver.ChromeOptions()
option.add_argument('headless')
browser = webdriver.Chrome(chrome_options=option)