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,为爬取详情页提供必要的参数。
相关推荐
FL162386312915 小时前
C# winform部署yolo26-obb旋转框检测的onnx模型演示源码+模型+说明
开发语言·c#
翔云12345615 小时前
(MySQLdb._exceptions.OperationalError) (2006, ‘MySQL server has gone away‘)
网络·python
大猫和小黄15 小时前
Java异常处理:从基础到SpringBoot实战解析
java·开发语言·spring boot·异常
我是一只小青蛙88815 小时前
Python办公自动化:6大实用库速览
python
半夏知半秋16 小时前
kcp学习-通用的kcp lua绑定
服务器·开发语言·笔记·后端·学习
Duang007_16 小时前
【LeetCodeHot100 超详细Agent启发版本】两数之和 (Two Sum)
java·人工智能·python
csbysj202016 小时前
并查集路径压缩
开发语言
企业对冲系统官16 小时前
基差风险管理系统集成说明与接口规范
大数据·运维·python·算法·区块链·github
JavaEdge.16 小时前
java.io.IOException: Previous writer likely failed to write hdfs报错解决方案
java·开发语言·hdfs
花酒锄作田16 小时前
[python]Flask - Tracking ID的设计
python·flask·pytest