js 爬虫抓取网页数据(动态网页抓取AJAX(Asynchronouse)异步JavaScript和XML的区别 )
优采云 发布时间: 2021-10-03 11:27js 爬虫抓取网页数据(动态网页抓取AJAX(Asynchronouse)异步JavaScript和XML的区别
)
动态网页抓取
AJAX (Asynchronouse JavaScript And XML) 异步 JavaScript 和 XML。通过在后台与服务器交换少量数据,Ajax 可以使网页异步更新。这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。如果内容需要更新,传统网页(不使用 Ajax)必须重新加载整个网页。因为传统的数据传输格式是XML语法。所以它被称为 AJAX。其实现在数据交互基本都是用JSON。使用AJAX加载的数据,即使使用JS将数据渲染到浏览器中,在右键->查看网页源代码中仍然看不到通过ajax加载的数据,只能看到使用这个url加载的html代码。
我们有两种方式获取ajax数据:
直接分析ajax调用的接口。然后通过代码请求这个接口。使用Selenium+chromedriver模拟浏览器行为获取数据。方式优缺点
分析界面
可以直接请求数据。无需做一些解析工作。代码量小,性能高。
解析接口比较复杂,尤其是一些被js混淆的接口,必须有一定的js基础。很容易被发现为爬虫。
硒
直接模拟浏览器的行为。浏览器可以请求的内容也可以使用 selenium 请求。爬虫更稳定。
很多代码。低性能。
我们接下来讲解使用selenium+chromedriver获取动态数据。
1.Selenium+chromedriver获取动态数据1.1.准备
Selenium 相当于一个机器人。它可以模拟人们在浏览器上的一些行为,并自动处理浏览器上的一些行为,如点击、填充数据、删除cookies等。chromedriver是一个驱动Chrome浏览器的驱动程序,可以用来驱动浏览器浏览器。当然,不同的浏览器有不同的驱动程序。下面列出了不同的浏览器及其相应的驱动程序:
铬:火狐:边缘:Safari:
我们这里使用 Chrome 来执行以下操作。
注意不同版本浏览器的驱动是不同的,请根据您的浏览器下载对应的版本。
我们使用以下代码来安装 selenium 库,
pip install selenium
1.2.打开和关闭网页
我们需要使用 selenium 实例化一个 Chrome 对象来模拟浏览器的操作,并使用 driver.get() 方法打开相应的网页。使用 driver.close() 方法关闭当前网页,或使用 driver.quit() 方法关闭浏览器。比如我们模拟打开一个百度页面,等待3秒后关闭,
from selenium import webdriver
import time
driver_path = r'D:\python_class\crawl\chromedriver.exe' # chromedriver.exe文件位置
driver = webdriver.Chrome(executable_path=driver_path) # executable_path为chromedriver.exe文件位置
driver.get('http://www.baidu.com') # 第一个参数为网站url
time.sleep(3)
driver.close() # 关闭当前页面
如果不想每次都设置executable_path参数,可以将chromedriver.exe文件放在chrome浏览器目录下,将目录地址添加到系统变量中的Path中,这样我们就不需要设置可执行路径参数。
1.3.阅读网页源码
我们可以直接使用driver.page_source来获取网页的源代码,比如我们获取百度页面的代码,
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
print(driver.page_source) # 打印页面源代码
driver.close() # 关闭当前页面
1.4. 定位元素
Selenium 支持基于类名、id、name 属性值、标签名、xpath、css 选择器或 By 方法定位元素。
方式示例
班级名称
inputTag = driver.find_elements_by_class_name("s_ipt")[0]
id值
inputTag = driver.find_element_by_id("kw")
名称属性值
inputTag = driver.find_element_by_name("wd")
标签名称
inputTag = driver.find_element_by_tag_name("输入")
xpath 语法
inputTag = driver.find_element_by_xpath('//input[@id="kw"]')
css 选择器
inputTag = driver.find_element_by_css_selector('#kw')
经过
使用By方法需要先导入,from mon.by import By, inputTag = driver.find_element(By.ID, “kw”)
1.5. 表单元素操作示例
操作输入框
发送密钥()
inputTag.send_keys('1')
点击元素
点击()
submintTag.click()
获取元素的指定属性
get_attribute()
inputValue.get_attribute('占位符')
1.6. 行为链
有时页面上的操作可能会有很多步骤,这时可以使用鼠标行为链类ActionChains来完成。我们使用行为链进行搜索,
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
# 实例化driver对象
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
inputTag = driver.find_element_by_id('kw') # 找到输入框
submitTag = driver.find_element_by_id('su') # 找到提交按钮
actions = ActionChains(driver) # 实例化行为链对象
actions.move_to_element(inputTag) # 焦点移动到输入框
actions.send_keys_to_element(inputTag, '美国病毒') # 提交内容
actions.move_to_element(submitTag) # 焦点移动到提交按钮
actions.click(submitTag) # 点击提交按钮
actions.perform() # 展示页面
我们还可以实现一些操作,
操作方法
单击而不释放鼠标
click_and_hold(元素)
右键点击
上下文点击(元素)
双击
双击(元素)
1.7.Cookie 操作
from selenium import webdriver
# 实例化driver对象
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
print(driver.get_cookies()) # 打印cookie信息,注意,这里是cookies()方法
print(driver.get_cookie('PSTM')) # 获取cookie中的PSTM信息,注意,这里是cookie()方法
print(driver.delete_cookie('PSTM')) # 删除cookie中的PSTM信息
1.8.页面操作1.8.1.等待页面
现在越来越多的网页使用 Ajax 技术,因此程序无法确定元素何时完全加载。如果实际页面等待时间过长,某个dom元素没有出来,而你的代码直接使用了这个WebElement,那么就会抛出NullPointer异常。为了解决这个问题。所以Selenium提供了两种等待方式:一种是隐式等待,另一种是显式等待。
我们先来看看隐式等待。
隐式等待调用driver.implicitly_wait()方法,我们可以设置等待时间,例如,
from selenium import webdriver
# 实例化driver对象
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.implicitly_wait(5) # 参数为等待时间。如果5秒内页面加载完成,则取消等待;否则,5秒后返回错误
print(driver.page_source)
接下来,显示操作。
显示等待是在执行获取元素的操作之前显示满足某个条件。也可以指定等待的最长时间,超过这个时间就会抛出异常。显示等待应在 selenium.webdriver.support.excepted_conditions 和 selenium.webdriver.support.ui.WebDriverWait 的预期条件下完成。示例代码如下:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# 实例化driver对象
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
element = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.ID, 'su')))
# 在5秒内,id值为su的标签加载完成后,则取消等待;否则,报错
这里有一些其他条件,
等待条件法
一个元素已加载
Presence_of_element_located()
页面上所有符合条件的元素都已加载完毕
Presence_of_all_emement_located()
一个元素可以被点击
element_to_be_cliable()
1.8.2.切换页面
有时窗口中有很多子标签页。这个时候必须切换。Selenium 提供了一个 switch_to_window 来切换。要切换到的特定页面可以在 driver.window_handles 中找到。页面会以列表的形式显示,可以使用列表下标来切换页面。例如,
from selenium import webdriver
# 实例化driver对象
driver = webdriver.Chrome()
driver.get('https://www.baidu.com') # 打开主页
driver.execute_script("window.open('http://www.zhihu.com')") # 以新窗口的形式打开新的页面
driver.execute_script("window.open('http://www.douban.com')")
print(driver.window_handles) # 窗口的句柄
driver.switch_to_window(driver.window_handles[0]) # 切换到页面列表中下标为0的页面
1.8.3.保存页面截图
save_screenshot() 方法可以保存页面的截图,例如,
from selenium import webdriver
from selenium.webdriver.common.by import By
# 实例化driver对象
driver = webdriver.Chrome()
driver.get('https://www.codingke.com') # 打开主页
driver.save_screenshot('codingke.png') # 参数为图片名称
1.9.设置代理不显示浏览器
我们可以通过添加浏览器选项来开启代理服务器并执行代码,而无需显示浏览器的操作过程。我们需要创建一个 ChromeOptions 对象,然后使用 add_argument() 方法添加选项,最后将 options 参数添加到 Chrome 对象中。例如,
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://175.42.123.88:9999") # 添加代理服务器
options.add_argument("--headless") # 不打开浏览器
options.add_argument("--disable-gpu") # 禁用GPU
driver = webdriver.Chrome(options=options)
driver.get('http://httpbin.org/ip')
print(driver.page_source)