python:Ajax爬取电影详情实战

复制代码
import json

import requests
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}'

def scrape_api(url):
    logging.info('scraping %s...',url)
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.json()
        logging.error('get invalid status code %s while scraping %s',response.status_code,url)
    except requests.RequestException:
        logging.error('error occurred while scraping %s',url,exc_info=True)

#爬取列表的方法
LIMIT = 10
def scrape_index(page):
    url = INDEX_URL.format(limit=LIMIT,offset=LIMIT*(page-1))
    return scrape_api(url)

#详情页的爬取方法
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)
        with open('chen.json','w',encoding='utf-8') as f:
            f.write(json.dumps(index_data))
        for item in index_data.get('results'):
            id = item.get('id')
            detail_data = scrape_detail(id)
            logging.info('detail data %s',detail_data)
if __name__=='__main__':
    main()

index_data.get('results')详解:

1. 先理解 index_data 是什么

在你的代码中,index_data = scrape_index(page) 这行代码的作用是调用 scrape_index 函数爬取某一页的电影列表数据,而 scrape_index 最终会通过 scrape_api 函数返回接口的 JSON 解析结果(字典类型)。

这个接口返回的 JSON 数据结构大概是这样的(示例):

json

复制代码
{
  "count": 100,
  "results": [
    {"id": 1, "name": "肖申克的救赎", "score": "9.7"},
    {"id": 2, "name": "霸王别姬", "score": "9.6"},
    ...
  ]
}

简单说:index_data 是一个包含 count(总数量)和 results(当前页电影列表)的字典。

2. index_data.get('results') 详解

这行代码是字典的 get 方法的典型应用,拆解来看:

(1)基础语法
复制代码
字典.get(key, 默认值)
  • 作用:从字典中获取 key 对应的 value;如果 key 不存在,返回 默认值(默认值不写则返回 None)。
  • 对比直接取值 字典[key]:
    • 直接取值:如果 key 不存在,会抛出 KeyError 异常,导致程序崩溃;
    • get 方法:如果 key 不存在,返回 None,程序不会崩溃,更安全。
(2)在你的代码中的具体作用
复制代码
for item in index_data.get('results'):
  • 第一步:index_data.get('results') 从 index_data 字典中获取 results 对应的 value(也就是当前页的电影列表,是一个列表);
  • 第二步:for item in ... 遍历这个列表,逐个取出每部电影的信息(item 是一个字典,包含 id、name 等字段);
  • 第三步:通过 id = item.get('id') 获取电影 ID,再调用 scrape_detail(id) 爬取详情页。
(3)为什么不用 index_data['results']?

假设接口返回的数据格式异常(比如没有 results 字段):

  • 用 index_data['results']:会直接抛出 KeyError: 'results',程序中断;

  • 用 index_data.get('results'):会返回 None,此时 for item in None 会抛出 TypeError,但你可以通过优化代码避免崩溃(比如加判断):

    复制代码
    results = index_data.get('results')
    if results:  # 确保results是非空列表
        for item in results:
            id = item.get('id')
            detail_data = scrape_detail(id)
            logging.info('detail data %s', detail_data)
    else:
        logging.warning('no results found in page %s', page)

3. 实际执行示例

假设 index_data 的数据是:

复制代码
index_data = {
  "count": 100,
  "results": [
    {"id": 1, "name": "肖申克的救赎"},
    {"id": 2, "name": "霸王别姬"}
  ]
}
  • index_data.get('results') 返回:[{"id": 1, "name": "肖申克的救赎"}, {"id": 2, "name": "霸王别姬"}];
  • 遍历后,item 依次是 {"id": 1, ...} 和 {"id": 2, ...};
  • 最终取出 id=1 和 id=2,分别爬取详情页。

总结

  1. index_data.get('results') 的核心是安全地从接口返回的字典中获取电影列表数据,避免因字段缺失导致程序崩溃;
  2. get 方法是爬虫开发中处理接口数据的常用技巧(接口返回格式可能异常),比直接取值更健壮;
  3. 遍历 results 列表的目的是获取每部电影的 id,为爬取详情页提供必要的参数。
相关推荐
Warson_L41 分钟前
高性能架构设计
python·go
databook1 小时前
新数据到手,先跑哪几步检查
python·数据分析
czq_26867194872 小时前
Python打卡第46天
开发语言·python
Flynt3 小时前
日涨4000星的OSINT工具,我拿Linus的用户名和一个随机字符串实测了一遍
python·安全
Evand J4 小时前
【MATLAB例程介绍】(17)永磁同步电机(PMSM)基于自适应无迹卡尔曼滤波(AUKF)的电流噪声在线估计。测量噪声协方差自适应与转速估计对比仿真
开发语言·matlab·卡尔曼滤波·无迹卡尔曼滤波·pmsm·电机滤波
BaiPeter5 小时前
ZPL文件预览
开发语言·c++
曲径海盗6 小时前
【Python 学习第 53 天】列表基础
python·学习笔记·编程入门
Dumbness6 小时前
群里 @ 机器人发"查订单",指令一条都没命中:微信群机器人在路由前漏掉的几步归一化
python·微信
用户1614840955456 小时前
用 M4 Pro 跑羽毛球视频 AI 分析(二):TrackNet MPS 加速 3.2 倍、卡尔曼滤波补漏与自动回合剪辑
python
用户4019925568616 小时前
基于对话树回溯的社媒评论流买方意图识别与噪音过滤实践
python