Titan笔记

  • 首页
  • Java
  • 数据结构
  • C语言
  • Web
  • 杂谈
  • 移动开发
  • 逸笔挥墨
Titan笔记
分享学习,研究与开发的点滴记忆
  1. 首页
  2. Python
  3. 正文

Python爬虫获取豆瓣TOP250电影详情

2020年6月23日 1361点热度 5人点赞 2条评论

介绍

偶然间看到豆瓣电影的TOP250榜单,于是突发奇想写了这个爬虫脚本。将通过爬取豆瓣电影TOP250的榜单列表获取电影详情页的URL,然后再爬取电影详情页URL中的内容,最终获得电影的名称,导演,演员,类别,制片国家/地区,语言,上映日期,片长和剧情简介等信息,经过一系列的处理后输出。

输出结果

最终结果将输出为JSON形式,为当前运行目录下的result.json,形式如下

Python爬虫获取豆瓣TOP250电影详情插图

代码

import requests
import threading
import re
import queue
import json

# Global HTTP Header Settings
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/78.0.3904.108 Safari/537.36",
}
detailUrls = []
exitFlag = False

jsonResult = []


# Retrieve the detail url
def getDetailUrl(source):
    pattern = r'<div class="hd">[\s]+<a href="(.*?)"'
    matcher = re.compile(pattern, re.S | re.M)
    result = matcher.findall(source)
    return result


# Get the movie details
def getMovieDetail(source):
    # Regex Patterns
    titlePattern = r'v:itemreviewed">(.*?)</span>'
    directorPattern = r'rel="v:directedBy">(.*?)</a>'
    starPattern = r'rel="v:starring">(.*?)</a>'
    categoryPattern = r'property="v:genre">(.*?)</span>'
    countryPattern = r'<span class="pl">制片国家/地区:</span>[\s]+(.*?)<'
    languagePattern = r'<span class="pl">语言:</span>[\s]+(.*?)<'
    releaseTimePattern = r'v:initialReleaseDate".*?>(.*?)</span>'
    runtimePattern = r'v:runtime"[\s]+content="(.*?)"'
    descriptionPattern = r'property="v:summary".*?>[\s]+(.*?)</span>'
    # Match Results
    titleMatch = re.search(titlePattern, source, re.S | re.M)
    directorMatch = re.findall(directorPattern, source, re.S | re.M)
    starMatch = re.findall(starPattern, source, re.S | re.M)
    categoryMatch = re.findall(categoryPattern, source, re.S | re.M)
    countryMatch = re.search(countryPattern, source, re.S | re.M)
    languageMatch = re.search(languagePattern, source, re.S | re.M)
    releaseTimeMatch = re.findall(releaseTimePattern, source, re.S | re.M)
    runtimeMatch = re.search(runtimePattern, source, re.S | re.M)
    descriptionMatch = re.search(descriptionPattern, source, re.S | re.M)
    # Build the Result Dict
    try:
        result = {
            "num": "",
            "title": titleMatch.group(1),
            "director": "/".join(directorMatch),
            "stars": "/".join(starMatch),
            "category": "/".join(categoryMatch),
            "country": countryMatch.group(1),
            "language": languageMatch.group(1),
            "release_time": "/".join(releaseTimeMatch),
            "runtime": runtimeMatch.group(1),
            "description": re.sub(r'[\s]{3,}', "", descriptionMatch.group(1))  # Delete the blanks
        }
        return result
    except Exception as e:
        return None


# Fetch the movie details from the detail url
def fetchDetails(detailUrl):
    r = requests.get(url=detailUrl, headers=headers, timeout=15)
    result = getMovieDetail(r.text)
    return result


# Fetch the movie list information
def fetchPage(startRecord):
    targetUrl = "https://movie.douban.com/top250?start=" + str(startRecord)
    r = requests.get(url=targetUrl, headers=headers, timeout=15)
    urlList = getDetailUrl(r.text)
    count = startRecord
    for detailUrl in urlList:
        with lock:
            count += 1
            detailUrls.append({"num": count, "url": detailUrl})
    pass


def detailJob():
    while not q.empty():
        target = q.get()
        targetUrl = target['url']
        targetNum = target['num']
        result = fetchDetails(targetUrl)
        if result is not None:
            result['num'] = targetNum
            jsonResult.append(result)
        pass


if __name__ == '__main__':
    lock = threading.Lock()
    q = queue.Queue()
    threadList = []
    # Create and Start the fetch page job
    print("Create and Start the fetch page job")
    page = 0
    for i in range(10):
        t = threading.Thread(target=fetchPage, args=(page,))
        threadList.append(t)
        t.start()
        page += 25
        pass
    for t in threadList:
        t.join()
        pass
    threadList.clear()
    print("Fetch detail urls finished")
    for url in detailUrls:
        q.put(url)
    # Create and Start the fetch details job
    print("Start to fetch details")
    for i in range(10):
        t = threading.Thread(target=detailJob)
        threadList.append(t)
        t.start()
    for t in threadList:
        t.join()
        pass
    print("Fetch Details Finished")
    print("Start to Write Data")
    jsonResult.sort(key=lambda x: x['num'])
    with open("result.json", "a+", encoding="utf-8") as fo:
        fo.write(json.dumps(jsonResult, indent=2, ensure_ascii=False))
    print("Over")
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: Python Python爬虫
最后更新:2020年6月23日

Titan

不为岁月流逝蹉跎,不为潮流的势头去附和

点赞
< 上一篇

文章评论

  • 阿sir不是吧

    感觉可以用BeautifulSoup来做,这样做出来的代码可能还稍微简洁一些

    2020年9月18日
    登录以回复
    • Titan

      @阿sir不是吧 习惯了使用正则表达式来匹配,当然用BS也是完全可以的,个人习惯使然。

      2020年9月20日
      登录以回复
  • 您需要 登录 之后才可以评论
    最新 热点 随机
    最新 热点 随机
    Docker配置IPv6容器网络支持 什么是Elastic Stack,ELK的发展历程 K8s中Pod的基本概念 云原生 - 浅谈容器基础与K8S架构设计 腾讯Serverless体验,使用TypeScript编写并部署云函数 Go-Proxy-Checker,一款基于Go编写的高性能代理服务器验证工具
    Docker配置IPv6容器网络支持 (三) Mybatis动态SQL语句 什么是Elastic Stack,ELK的发展历程 MySQL ORDER BY,GROUPBY 与各种JOIN [数据结构] 稀疏矩阵的存储 Linux 网络优化指南 - 改善Linux的网络性能
    分类
    • Android
    • C语言
    • Elasticsearch
    • Hadoop
    • Hive
    • Java
    • JavaWeb
    • Kubernetes
    • Linux运维之道
    • Mybatis学习笔记
    • Python
    • SpringCloud
    • Web
    • Web前端
    • Web后端
    • 云原生
    • 并发编程
    • 开发工具
    • 数据库
    • 数据结构
    • 杂谈
    • 移动开发
    • 移动测试
    • 诗词歌赋
    • 软件测试
    • 逸笔挥墨
    • 随摘
    标签聚合
    Java 链式存储 数据结构 JavaWeb Apache-Hive 二叉树 Python Mybatis学习笔记

    COPYRIGHT © 2013-2021 Titan. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    豫ICP备20001822号-1

    豫公网安备 41010502004418号