什么是AJAX
AJAX(Asynchronouse JavaScript And XML)异步JavaScript和XML,在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用Ajax)如果需要更新内容,必须重载整个网页页面。
因为传统的在传输数据格式方面,使用的是XML语法,因此叫做AJAX,其实现在数据交互基本上都是使用JSON,很少使用XML了。
使用AJAX加载的数据,即使执行了JS代码 将数据渲染到了浏览器中,在右键-查看网页源代码还是不能看到通过ajax加载的数据。
查看源代码看到的是服务器最原始的HTML,不包含ajax生成的HTML元素。
如下图:可以看到页面中引入了很多js文件和css文件,这些文件有的是用来动态生成元素的,有的是其他用途。反正除了这些文件路径和一些JavaScript代码,在页面中获取不到任何有用的网页信息。
而审查元素则可以看到生成的各种HTML元素,这些元素都是浏览器通过对引入的js和css进行解析生成的,生成这些元素使用的是ajax技术。
如下图:
获取ajax数据的方式
1、直接分析ajax调用的接口,然后通过代码请求这个接口,俗称怼加密(找加密、网页js逆向),需要很强的前端 JavaScript功底。
优点:直接可以请求到数据,不需要做一些解析工作,代码量少,性能高
缺点:分析接口比较复杂,特别是一些通过js混淆的接口,要有一定的js功底;容易被发现是爬虫
2、使用Selenium+chromedriver模拟浏览器行为获取数据,使用代码模拟人工操作,用代码控制浏览器,得到的数据是和审查元素一样的,也就是说浏览器上能看到的都能得到。
优点:直接模拟浏览器的行为,浏览器能请求到的,使用selenium也能请求到;爬虫更稳定
缺点:代码量多,性能低
一般在post请求的时候,比如注册或登陆时,提交数据经常是加密的(一般密码会进行加密),这种都是需要找出加密方法,并且在post请求的时候模拟出加密数据。
随着慢慢普及,现在js逆向几乎每个人都会一些,只是有些js混淆的厉害,着实难搞。
Selenium+chromedriver获取动态数据
Selenium相当于是一个机器人,可以模拟人类在浏览器上的一些行为,自动处理浏览器上的一些行为,比如点击,填充数据,删除cookie等。
chromedriver是一个驱动Chrome浏览器的驱动程序,使用它才可以驱动浏览器。
当然,针对不同的浏览器有不同的driver。
Chrome:https://sites.google.com/a/chromium.org/chromedriver/downloads
Firefox:https://github.com/mozilla/geckodriver/releases
Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Safari:https://webkit.org/blog/6900/webdriver-support-in-safari-10/
安装Selenium和chromedriver
安装Selenium:
Selenium有很多语言的版本,java、ruby、python等。
python版本安装:
pip install selenium
安装chromedriver:
通过上面的地址,下载完成后,放到不需要权限的纯英文目录下就可以了。
快速入门
一个获取百度首页的例子
from selenium import webdriver
# chromedriver所在的绝对路径
driver_path = r'D:\ProgramApp\chromedriver\chromedriver.exe'
# 使用webdriver.Chrome初始化一个对象(driver),并且指定chromedriver的路径
driver = webdriver.Chrome(executable_path=driver_path)
driver.get("https://www.baidu.com/") # 请求网页
print(driver.page_source) # 通过page_source获取网页源代码
selenium常用操作
更多教程请参考:http://selenium-python.readthedocs.io/installation.html#introduction
关闭页面
driver.close():关闭当前页面
driver.quit():退出整个浏览器
定位元素
1、根据id查找元素
submitTag = driver.find_element_by_id('su')
# 另一种方式
from selenium.webdriver.common.by import By # 导入By模块
submitTag1 = driver.find_element(By.ID,'su')
2、根据类名查找元素
submitTag = driver.find_element_by_class_name('su')
# 另一种方式
from selenium.webdriver.common.by import By # 导入By模块
submitTag1 = driver.find_element(By.CLASS_NAME,'su')
3、根据name属性的值查找元素
submitTag = driver.find_element_by_name('email')
# 另一种方式
from selenium.webdriver.common.by import By # 导入By模块
submitTag1 = driver