您的当前位置:首页>全部文章>文章详情

【Python】第五章 Ajax数据爬取

CrazyPanda发表于:2023-12-03 21:35:21浏览:643次TAG:

目录


  • 使用requests获取的是原始HTML文档

  • 浏览器中的页面是JavaScript处理数据后生成的结果

  • 数据的来源

    • 通过Ajax加载

    • 包含在HTML文档中

    • 经过JavaScript和特定算法计算后生成

  • Ajax加载数据

    • 原始页面最初不包含某些数据

    • 当原始页面加载成功后,再向服务器请求某个接口获取数据

    • 然后将数据处理并呈现在网页上

    • 发送Ajax请求

    • 方式:异步

1. 什么是Ajax

  • Ajax(Asynchronous JavaScript and XML):异步的 JavaScript 和 XML

    • 不是一门编程语言

    • 利用 JavaScript 在保证页面不被刷新、页面链接不改变的情况下与服务器交换数据并更新部分网页的技术

1.1 实例引入

  • 下滑查看更多

  • 下滑后加载的动画:Ajax 加载的过程

1.2 基本原理

  • 从Ajax请求到网页更新的这个过程可以分为3步

    • 发送请求

    • 解析内容

    • 渲染网页

发送请求

  • JavaScript对Ajax最底层的实现

var xmlhttp;
if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
} else {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

// 监听服务器返回响应
xmlhttp.onreadystatechange = function() {
    // 解析响应内容
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
    }
}

// 打开服务器链接
xmlhttp.open("POST", "/ajax/", true);

// 向服务器发送强求
xmlhttp.send();

解析内容

var xmlhttp;
if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
} else {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange = function() {
    // 解析响应内容
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
    }
}

xmlhttp.open("POST", "/ajax/", true);
xmlhttp.send();

渲染网页

var xmlhttp;
if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
} else {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        // 更改网页内容
        document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
    }
}

xmlhttp.open("POST", "/ajax/", true);
xmlhttp.send();

2. Ajax分析方法

2.1 分析案例

  • 微博 (weibo.cn)

  • Ajax 的请求类型:xhr

  • 如果 Request Headers 中有一个信息为XMLHttpRequest,则此请求就是 Ajax 请求

    • 以 getIndex 开头的请求

  • 可以在 Preview 查看响应的内容

  • 也可以在 Response 查看真实返回的数据

2.2 过滤请求

  • 点击 Network 中的 XHR 选项,显示所有的 Ajax 请求

3. Ajax分析与爬取实战

  • 爬取 Scrape | Movie

    • 数据请求是通过 Ajax 实现的

    • 页面内容通过 JavaScript 渲染出来的

    • 只是呈现样式是一样的

    • 与 2.5(Scrape | Movie)不同

3.1 爬取目标

  • 爬取电影的名称、封面、类别、上映时间、评分、剧情简介等内容

  • 分析页面数据的加载逻辑

  • 用 requests 实现 Ajax 数据的爬取

  • 将每部电影数据分别保存到 MongoDB 数据库

3.2 初步探索

import requests

url = "https://spa1.scrape.center/"
html = requests.get(url).text

print(html)
  • 获取到的 html 资源较少

  • 整个页面都是JavaScript渲染得到的,浏览器执行了HTML中引用的JavaScript文件,JavaScript通过调用一些数据加载和页面渲染方法,才最终呈现出浏览器中的显示效果

  • 数据一般是通过Ajax加载的,JavaScript在后台调用Ajax数据接口

3.3 爬取列表页

分析

  • 请求URL的limit恒定为10,offset为已经已经翻过的电影数量(( 当前页数 − 1 ) ∗ 10 (当前页数-1)*10(当前页数−1)∗10)

  • 版权声明:本文为CSDN博主「His Last Bow」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

  • 原文链接:https://blog.csdn.net/BlackOrnate/article/details/134735396

  • 根据响应内容可以发现所需数据皆在其中

实现

基础配置
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s: %(message)s')

INDEX_URL = "https://spa1.scrape.center/api/movie/?limit={limit}&offset={offset}"
爬取页面内容(获取页面的JSON内容)
import requests

def scrape_api(url):
    logging.info(f"scraping {url}...")
    try:
        response = requests.get(url)

        if response.status_code == 200:
            return response.json()
        logging.error(
            f"Status code: {response.status_code} while scraping {url}")
    except requests.RequestException:
        logging.error(f"Error while scraping {url}", exc_info=True)
爬取列表页(爬取指定列表页)
LIMIT = 10

def scrape_index(page):
    url = INDEX_URL.format(limit=LIMIT, offset=LIMIT * (page - 1))
    return scrape_api(url)

合并

import logging
import requests

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s: %(message)s')

INDEX_URL = "https://spa1.scrape.center/api/movie/?limit={limit}&offset={offset}"
LIMIT = 10


def scrape_api(url):
    logging.info(f"scraping {url}...")
    try:
        response = requests.get(url)

        if response.status_code == 200:
            return response.json()
        logging.error(
            f"Status code: {response.status_code} while scraping {url}")
    except requests.RequestException:
        logging.error(f"Error while scraping {url}", exc_info=True)


def scrape_index(page):
    url = INDEX_URL.format(limit=LIMIT, offset=LIMIT * (page - 1))
    return scrape_api(url)

3.4 爬取详情页

分析

  • url:最后的一个参数为此电影的id

  • 电影的id:Ajax请求返回的数据中含有电影对应的id

实现

爬取详情页
DETAIL_URL = "https://spa1.scrape.center/api/movie/{id}"


def scrape_detail(id):
    url = DETAIL_URL.format(id=id)
    return scrape_api(url)
串联调用
TOTAL_PAGE = 10


def main():
    for page in range(1, TOTAL_PAGE + 1):
        index_data = scrape_index(page)

        for item in index_data.get("results"):
            id = item.get("id")
            detail_data = scrape_detail(id)
            logging.info(f"detail data {detail_data}")
            

if __name__ == "__main__":
    main()

合并

import logging
import requests

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s: %(message)s')

INDEX_URL = "https://spa1.scrape.center/api/movie/?limit={limit}&offset={offset}"
DETAIL_URL = "https://spa1.scrape.center/api/movie/{id}"
LIMIT = 10
TOTAL_PAGE = 10


def scrape_api(url):
    logging.info(f"scraping {url}...")
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.json()
        logging.error(
            f"Status code: {response.status_code} while scraping {url}")
    except requests.RequestException:
        logging.error(f"Error while scraping {url}", exc_info=True)


def scrape_index(page):
    url = INDEX_URL.format(limit=LIMIT, offset=LIMIT * (page - 1))
    return scrape_api(url)


def scrape_detail(id):
    url = DETAIL_URL.format(id=id)
    return scrape_api(url)


def main():
    for page in range(1, TOTAL_PAGE + 1):
        index_data = scrape_index(page)

        for item in index_data.get("results"):
            id = item.get("id")
            detail_data = scrape_detail(id)
            logging.info(f"detail data {detail_data}")


if __name__ == "__main__":
    main()

3.5 保存数据(MongoDB)(后期补充)


猜你喜欢

【Python】利用Python和WebDriver扩展自动化处理网页的滑动验证码
利用Python和WebDriver扩展自动化处理网页的滑动验证码引言:随着互联网的快速发展,为了确保网站的安全性和用户体验,很多网站都采用了各种形式的验证码。其中,滑动验证码被广泛应用于验证用户的真实性。但对于使用自动化测试工具的测试人员来说,滑动验证码却成为了一道难以逾越的鸿沟。然而,利用Python的selenium库以及WebDriver,我们可以轻松地扩展自动化测试脚本来处理滑动验证码。本文将介绍如何使用Python和WebDriver实现滑动验证码的自动化处理,并附上相应的
发表于:2023-12-28 浏览:308 TAG:
【Python】简单指南:逐步安装matplotlib并制作引人注目图表
一步步教你安装matplotlib,轻松绘制漂亮图表,需要具体代码示例在数据分析和数据可视化领域,matplotlib 是一个非常强大的 Python 库。它为我们提供了丰富的绘图功能,可以轻松地创建各种类型的图表。本文将向大家介绍如何安装 matplotlib,并提供一些具体的代码示例,以帮助大家更好地掌握该库。步骤一:安装 Python首先,我们需要安装 Python。在官方网站(https://www.python.org/downloads/)上可以下载最新的 Python 版本。根据你
发表于:2024-01-12 浏览:277 TAG:
【Python】第七章 JavaScript动态渲染页面爬取
目录1. Selenium的使用隐式等待显式等待获取属性获取文本值获取ID、位置、标签名和大小单个节点多个节点安装selenium安装WebDriverWebDriver配置1.1 准备工作1.2 基本用法1.3 初始化浏览器对象1.4 访问页面1.5 查找节点1.6 节点交互1.7 动作链1.8 运行JavaScript1.9 获取节点信息1.10 切换Frame1.11 延时等待1.12 前进和后退1.13 Cookie1.14 选项卡管理1.15 异常处理1.16 反屏蔽1.17 无头模式
发表于:2023-12-03 浏览:853 TAG:
【Python】了解Django框架:从入门到精通
Django是一个流行的Python Web框架,它为开发Web应用程序提供了一种高效而强大的方式。本文将从入门到精通,介绍Django的基础知识,并提供具体代码示例。安装Django在使用Django之前,需要确保已在计算机上安装了Python。然后,可以使用以下命令安装Django:pip install Django创建Django项目要创建一个新的Django项目,可以使用以下命令:django-admin startproject <pro
发表于:2024-01-19 浏览:293 TAG:
【Python】探索matplotlib颜色映射:创造绚丽绘图作品
了解matplotlib颜色表:打造炫彩绘图作品引言:在数据可视化领域中,matplotlib是一个非常强大且广泛使用的Python库。它提供了丰富的绘图功能,但其中一个特别令人印象深刻的功能是可以使用各种颜色表进行绘图,从而打造炫彩绘图作品。在本文中,我们将深入了解matplotlib颜色表的使用,并提供具体的代码示例。一、颜色表的概念:颜色表是一种将数据值映射为颜色的方法。它是一个由多个颜色组成的序列,其中每个颜色对应于一定范围内的数据值。使用颜色表可以将数据值可视化为连续的颜色渐变,从而更
发表于:2024-01-11 浏览:352 TAG:
【Python】Python中的列表和元组的性能比较和选择原则是什么?
Python中的列表和元组的性能比较和选择原则是什么?在Python中,列表和元组是两种常见的数据结构。它们都可以用来存储一组数据,但有一些重要的区别。本文将从性能角度比较列表和元组,并给出选择原则的建议。访问速度:在访问单个元素时,元组的性能通常比列表更好。这是因为元组是不可变的,所以Python可以在内存中更快地定位元组的元素。而列表是可变的,每次访问元素都需要进行一系列的索引操作和操作内存访问。下面是一个测试示例,比较了访问列表和元组中相同位置元素的时间:import timei
发表于:2024-01-21 浏览:312 TAG:
【Python】第一章 爬虫基础
目录1. HTTP 基本原理1.4.1 响应状态码1.4.2 响应头1.4.3 响应体1.3.1 请求方法1.3.2 请求的网址1.3.3 请求头1.3.4 请求体1.1 URI 和 URL1.2 HTTP 和 HTTPS1.3 请求1.4 响应2. Web 网页基础2.1.1 HTML2.1.2 CSS2.1.3 JavaScript2.1 网页的组成2.2 网页的结构2.3 节点树及节点间的关系2.4 选择器3. 爬虫的基本原理3.1.1 获取网页3.1.2 提取信息3.1.3 保存数据3.
发表于:2023-12-02 浏览:500 TAG:
【Python】pandas数据分析技巧全面解析:从初学到专家
Pandas是Python中最常用的数据分析库之一,它为数据处理和分析提供了丰富的功能和高效的工具。本文将从入门到精通,介绍一些常用的Pandas数据分析方法,并提供具体的代码示例。一、数据导入与基本操作导入Pandas库和数据集首先,需要导入Pandas库并加载数据集。可以使用以下代码示例:import pandas as pd   # 加载CSV文件 data = pd.read_csv('data.csv&#39
发表于:2024-01-13 浏览:312 TAG:
【Python】使用Python获取年份和星期几的月份
处理时间是任何日常活动中最重要的方面之一。在本文中,我们将讨论如何使用 Python 从年份和工作日获取月份。我们将利用Python 的两个最流行的库,即calendar 和datetime,来处理月份、年份等。这两个库都提供了几种处理时间的内置方法。如果我们处理这样的库,我们不需要专门关心像闰年这样具有挑战性的任务。使用日历库Python 中的日历库提供了处理日历和日期的有用函数和类。它提供了一系列功能来生成日历、操作日期和执行与日历相关的计算。它简化了与生成日历、计算工作日和操作日期相关的任
发表于:2024-01-14 浏览:286 TAG:
【Python】解决实际问题:Matplotlib折线图实战指南
实战指南:使用matplotlib绘制折线图解决实际问题引言数据可视化在解决实际问题中起着重要的作用。而折线图是其中最常用和常见的一种图表类型。在这篇文章中,我们将介绍如何使用Python的matplotlib库来绘制折线图,并通过具体的代码示例来解决实际问题。一、准备工作在开始之前,我们需要安装matplotlib库。打开终端或命令提示符,输入以下命令来安装最新版本的matplotlib库:pip install matplotlib安装完成后,我们就可以开始使用matpl
发表于:2024-01-17 浏览:319 TAG: