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 是一个字典,包含 idname 等字段);
  • 第三步:通过 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=1id=2,分别爬取详情页。

总结

  1. index_data.get('results') 的核心是安全地从接口返回的字典中获取电影列表数据,避免因字段缺失导致程序崩溃;
  2. get 方法是爬虫开发中处理接口数据的常用技巧(接口返回格式可能异常),比直接取值更健壮;
  3. 遍历 results 列表的目的是获取每部电影的 id,为爬取详情页提供必要的参数。
相关推荐
微爱帮监所写信寄信2 小时前
微爱帮监狱写信寄信工具服务器【Linux篇章】再续:TCP协议——用技术隐喻重构网络世界的底层逻辑
linux·服务器·开发语言·网络·网络协议·小程序·监狱寄信
天呐草莓2 小时前
集成学习 (ensemble learning)
人工智能·python·深度学习·算法·机器学习·数据挖掘·集成学习
BBB努力学习程序设计2 小时前
Python多线程与多进程编程实战指南
python
雪落无尘处2 小时前
Anaconda 虚拟环境配置全攻略+Pycharm使用虚拟环境开发:从安装到高效管理
后端·python·pycharm·conda·anaconda
赵庆明老师2 小时前
VS2026扩展插件Visual Commander
java·开发语言
额呃呃2 小时前
信号量唤醒线程的实际机制
java·开发语言·jvm
Amelia1111112 小时前
day36
python
程序员阿鹏2 小时前
怎么理解削峰填谷?
java·开发语言·数据结构·spring·zookeeper·rabbitmq·rab