5.parsel库获取豆瓣top250榜单

"""
需求:获取豆瓣电影TOP250榜单
①发起访问:浏览器发起访问目标网页
②解析数据:提取网页中的目标信息
③数据存储:将数据保存为本地CSV文件
④数据筛选:筛选出需求的数据
"""

import requests
import parsel
import csv

# 创建文件对象
f = open("top250.csv", "a", encoding="utf‑8‑sig", newline="")
csv_writer = csv.DictWriter(f, [
            "电影名",
            "导演",
            "主演",
            "年份",
            "国家",
            "类型",
            "评分",
            "简介",
            "详情页"
    ]
)

# 写入表头
csv_writer.writeheader()
# 翻页获取1-10页数据
for page in range(10):
    print(f"正在爬取第{page+1}页的数据.......")
    start_num = page * 25
    url = f'https://movie.douban.com/top250?start={start_num}&filter='
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
    }
    # 发送请求
    response = requests.get(url=url,headers=headers,verify=False)
    # print(response.text)
    # 转成可解析对象
    selector = parsel.Selector(response.text)

    # 获取所有电影数据标签
    lis = selector.css(".grid_view li")

    # for循环遍历,把列表里的元素一个一个取出来
    for li in lis:
        """
        .hd a span:nth-child(1)::text --> 提取标签class类名为hd下面a标签下面第一个span标签里面文本数据 
        .hd --> class类名为hd标签
        a --> a 标签
        get()  --> 提取第一个标签数据:返回字符串
        getall() --> 提取所有标签数据:返回列表
        strip() --> 字符串方法,去除左右两端空格
        split() --> 字符串方法,以某个字符串作为分割,反馈列表
        replace() --> 字符串方法,替换
        """
        title = li.css(".hd a span:nth-child(1)::text").get()  # 电影名
        info_list = li.css(".bd p:nth-child(1)::text").getall() # 电影信息

        # 第1行:导演和主演,第2行:年份/国家/类型
        # \xa0 是不间断空格( ),豆瓣页面大量使用,必须先替换成普通空格,否则 split 会切不开
        info1 = info_list[0].strip().replace("\xa0", " ") if len(info_list) >= 1 else ""
        info2 = info_list[1].strip().replace("\xa0", " ") if len(info_list) >= 2 else ""

        # 导演/主演:用 "   " 分隔,不一定有主演
        parts1 = info1.split("   ") if info1 else []
        director = parts1[0].replace("导演: ", "").split(" ")[0] if len(parts1) >= 1 else ""
        actor = parts1[1].replace("主演: ", "").split(" ")[0] if len(parts1) >= 2 else ""

        # 年份/国家/类型:用 " / " 分隔,替换\xa0后即可正确拆分
        parts2 = info2.split(" / ") if info2 else []
        year = parts2[0].strip() if len(parts2) >= 1 else ""
        country = parts2[1].strip() if len(parts2) >= 2 else ""
        movie_type = parts2[2].strip() if len(parts2) >= 3 else ""

        score = li.css(".rating_num::text").get()  # 评分
        intro = li.css(".quote span::text").get()  # 简介
        link = li.css(".hd a::attr(href)").get()  # 详情页链接地址

        data_dict = {
            "电影名": title,
            "导演": director,
            "主演": actor,
            "年份": year,
            "国家": country,
            "类型": movie_type,
            "评分": score,
            "简介": intro,
            "详情页": link
        }
        # print(info_list[1])
        # print(title,director,actor,year,country,movie_type,score,intro,link)
        csv_writer.writerow(data_dict)
        print(data_dict)
f.close()

"""
https://movie.douban.com/top250 或 https://movie.douban.com/top250?start=0&filter=   第1页
https://movie.douban.com/top250?start=25&filter=  第2页
https://movie.douban.com/top250?start=50&filter=  第3页
"""

效果如下:
image

posted @ 2026-08-21 17:09  無心的Man  阅读(22)  评论(0)    收藏  举报