网络数据采集 (爬虫) —— 加载动态页面( 4 )
1.了解Ajax
Ajax -------> 为页面生成动态内容的一种技术
-
Asynchronous JavaScript and XML(XML已经被JSON取代了,没有换成新名字)
-
浏览器可以在不中断用户体验的情况下,向服务器发起异步请求(在浏览器后台发生,用户感知不到)
-
服务器在收到浏览器发出的异步请求之后会返回数据,数据通常都是使用JSON格式
-
浏览器获得JSON数据之后,就会使用JavaScript对页面进行局部渲染,生成动态内容
如果要抓取这些动态内容,我们可以在浏览器的开发者工具中截获异步请求,找到获取动态数据的URL
获取json数据之后去在线解析工具解析
2.通过URL获取动态内容
import requests
import bs4
"""
JavaScript逆向-----》找到提供动态内容的URL
- 浏览器开发者工具 ------->Network -----> XHR
- 专业的抓包工具(抓url更简单一些)------> Charles/ Fiddler / wireshark- 科学家级别"""
def download_picture(url):
resp = requests.get(url)
# 获取图片名
filename = url[url.rfind('/') + 1:]
# 写文件夹
with open(f'image360/{filename}', 'wb') as file:
file.write(resp.content)
def main():
# 找到提供动态内容的URL
resp = requests.get('https://image.so.com/zjl?ch=photography&sn=0')
data_dict = resp.json()
for image_dict in data_dict['list']:
print(image_dict['qhimg_url'])
if __name__ == '__main__':
main()
3.抓包工具charles的用法:
网址:https://www.jianshu.com/p/bddaf8fcfce8
安装:pip install selenium
驱动程序 :
1.先检查谷歌浏览器版本 ----> 菜单 ----> 帮助 ----> 关于
2.在http://npm.taobao.org/mirrors/chromedriver中,找到最接近自己谷歌浏览器版本的驱动
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XXTiP38t-1615619897976)(C:\Users\72405\Desktop\爬虫图片\QQ图片20210313115930.png)]
3.Chromedriver下载解压之后,粘贴到虚拟环境下的Scripts目录,运行程序就可以自动 打开界面了
"""
用Python程序驱动浏览器工作,直接获取页面加载动态内容之后的HTML代码,
要做到这一点需要三方库selenium的支持,这个库也被广泛应用于自动化测试
-- Selenium IDE ---->浏览器插件 ----> 录制用户操作然后重复播放
-- Selenium WebDriver ----> 驱动浏览器 ----> 模拟用户操作
-- Selenium Remote Control ----> 多机控制
"""
from selenium import webdriver
import time
# 1.创建浏览器对象
browser = webdriver.Chrome()
# 要在venv下Scripts放chromdriver
# 2.指定URL加载界面
browser.get('https://image.so.com/')
# 通过ID获取页面元素(输入框)
kw_input = browser.find_element_by_id('search_kw')
# 模拟用户输入行为
kw_input.send_keys('易烊千玺')
# 通过CSS选择器获取页面元素(按钮)
search_button = browser.find_element_by_css_selector('button[type="submit"]')
search_button.click()
# 模拟用户向下滚动页面
for _ in range(20):
# 让浏览器执行JavaScript代码通过window对象控制垂直滚动条向下滚动
browser.execute_script('window.scrollTo(0, window.scrollY + 500)')
# 每次向下滚动休眠0.2秒
time.sleep(0.2)
# 设置一个隐式等待时间(当你获取元素的时候,如果元素暂时还没有出来,可以等待指定时间)
browser.implicitly_wait(10)
# 3. 通过浏览器对象的find_elements_by_xxx方法获取页面元素,获取'img'标签
imgs_list = browser.find_elements_by_tag_name('img')
for img in imgs_list:
# 4.如果要获取标签里面的内容可以使用标签对象(WebElement)的text属性
# 如果要获取的是标签里面的属性,就可以使用标签对象的get_attribute方法
print(img.get_attribute('src'))
开发者工具 ------> Network -------> XHR(XML HttpRequest) and Fetch
JavaScript逆向
有些网站数据接口做了加密:
用Python驱动浏览器对象加载所有的内容(使用selenium)
selenium ----> find_elements_by_css_selector
4.启用无头浏览器
"""
启用无头浏览器模式
"""
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
# 通过ChromeOptions对象可以指定启动浏览器时用到的参数
options = webdriver.ChromeOptions()
options.add_argument('--headless')
# 关掉浏览器窗口上方显示的“Chrome正受到自动测试软件的控制”
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=options)
# 执行Chrome开发者协议(CDP)命令,在加载新页面时执行指定的JavaScript代码
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
# 设置窗口尺寸
browser.set_window_size(1280, 960)
browser.get('https://www.baidu.com/')
# 隐式等待
browser.implicitly_wait(10)
kw_input = browser.find_element_by_css_selector('#kw')
kw_input.send_keys('Python')
kw_input.send_keys(Keys.ENTER)
# 使用显示等待的方式等到搜索结果的出现 -------> # 31
wait = WebDriverWait(browser, 10) # browser是浏览器
# 通过WebDriverWait对象的until方法设置等待的期望条件,也是显示等待
# 这个函数里面要放二元组
wait.until(expected_conditions.presence_of_element_located(
(By.CSS_SELECTOR, 'div.result')
))
# time.sleep(1)
# 为浏览器窗口生成一个快照并保存成图片文件
browser.get_screenshot_as_file('results.png')
# 关掉浏览器窗口
browser.close() # close也可以改成quit
print('程序结束!')