综合实例--爬取豆瓣所有电影分类

需求简介

获取豆瓣电影所有的分类
在这里插入图片描述
在各种分类的电影中按照次序找到前20部电影,获取其信息,如电影名称,电影海报,评价人数,演员列表等等
在这里插入图片描述
拟要达到的效果,将电影信息存储在csv文件中,所有的电影海报存放在同级文件夹中
在这里插入图片描述

需要用到的库

简介 笔者的博客传送门
csv 用于将电影信息写入csv文件中 暂未完成
selenium 动态加载网页数据,并从网页源码中找到电影信息 暂未完成
requests 发送网页访问请求 暂未完成
os 文件夹或保存路径的管理 os库
bs4 解析网页源码并从中获得想要的数据信息 BeautifulSoup库
re 解析解析网页内容 re 模块
threading 多线程高效执行任务 暂未完成

流程分类在这里插入图片描述

分步实现

  1. 建立一个电影类
class Movie:
    def __init__(self, type):
        self.img = None		# 电影海报
        self.name = None	# 名称
        self.type = type	# 类型
        self.rank = None	# 排名
        self.crew = None	# 演员列表
        self.rating = None	# 评分
        self.comment = None	# 评价
        self.url = None		# 网址

    def get(self):
        return [self.type, self.rank, self.name, self.crew, self.rating, self.comment, self.url]
  1. 创建获取电影类型的函数
def type_url():
	# 设置请求头,请求得到所有电影类型
    headers = {
    
    'user-agent': 'Mozzila/5.0'}
    resp = requests.get(start_url, headers=headers)
    # 使用bs4库解析网页内容
    soup = BeautifulSoup(resp.text, 'html.parser')
    # 定位网页信息
    type_list = soup.find_all('a', href=re.compile('^/typerank'))
    for item in type_list:
    	# 获取类型名
        type_name = item.text
        print(type_name)
        # 调用函数,下载电影信息
        download_type(type_name, item['href'])
        time.sleep(3)
  1. 创建获取电影海报的函数
def image_movie_image(url, image_name):
    image_save_path = Image_path + os.sep + image_name
	# 请求电信海报所在的网址
    try:
        resp = requests.get(url, proxies={
    
    'ip': nums_list[random.randint(0, len(nums_list) - 1)]})
        with open(image_save_path, 'wb+')as f:
            f.write(resp.content)		# 将海报图片写入文件夹
    except:
        pass
  1. 创建获取电影信息的函数
def download_type(type_name, url):
    driver.get(bath_url + url)
    saving_path = save_path + os.sep + type_name + '.csv'
    # 五次拖动页面到最底部动态加载电影信息
    for i in range(5):
        target = driver.find_element(by='id', value='footer')
        driver.execute_script('arguments[0].scrollIntoView();', target)
        time.sleep(1)    
    count = 0
    try:
        with open(saving_path, 'a+', newline='') as f:
            csv_f = csv.writer(f)		# 创建一个csv对象
            csv_f.writerow(headers)		# 写入行列标题
            for item in driver.find_elements('xpath', '//div[@class="movie-content"]'):
                try:
                    movie = Movie(type_name)		# 将创建的类实例化为对象
                    # 获取每个对象的属性值
                    movie.url = item.find_element('tag name', 'a').get_attribute('href')
                    movie.name = item.find_element('class name', 'movie-name-text').text
                    movie.img = movie.name + '.jpg'
                    movie.rating = item.find_element(By.CLASS_NAME, 'rating_num').text
                    movie.crew = item.find_element('class name', 'movie-crew').text
                    movie.rank = item.find_element('class name', 'rank-num').text
                    movie.comment = int(re.sub('\D', '', item.find_element('class name', 'comment-num').text))
                    # 使用movie对象的get方法返回其属性,将其属性按行写入csv文件
                    csv_f.writerow(movie.get())
                    # 获取每部电影海报的网址,调用函数,多线程开启下载
                    image_url = item.find_element(by=By.CLASS_NAME, value='movie-img').get_attribute('src')
                    threading.Thread(target=image_movie_image, args=(image_url, movie.img,)).start()
                    # 开启计数,每扒取一部电影次数加一,次数大于20停止该类型电影的扒取
                    count += 1
                    if count > 20:
                        break
                    time.sleep(1)
                except:
                    pass
    except Exception as e:
        print(e)    

完整实现

import csv
import threading
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import requests
import re, os, random

driver = webdriver.Chrome()		# 创建一个浏览器驱动
save_path = 'E:\\coding\\recourses\\douban1'
if not os.path.exists(save_path):	# 不存在目录则创建
    os.makedirs(save_path)
Image_path = save_path+os.sep+'image'
bath_url = 'http://movie.douban.com'
start_url = bath_url + '//chart'
headers = ['电影类型', '排名', '电影名称', '演员', '评分', '评价', 'url']


# 获取代理ip
url1 = 'https://www.kuaidaili.com/free/inha/'
response = requests.get(url=url1)
mode = re.compile('(\d+\.\d+\.\d+\.\d+)')
nums_list = mode.findall(response.text)
    

class Movie:
    def __init__(self, type):
        self.img = None  # 电影海报
        self.name = None  # 名称
        self.type = type  # 类型
        self.rank = None  # 排名
        self.crew = None  # 演员列表
        self.rating = None  # 评分
        self.comment = None  # 评价
        self.url = None  # 网址

    def get(self):
        return [self.type, self.rank, self.name, self.crew, self.rating, self.comment, self.url]


def type_url():
    # 设置请求头,请求得到所有电影类型
    headers = {
    
    'user-agent': 'Mozzila/5.0'}
    resp = requests.get(start_url, headers=headers)
    # 使用bs4库解析网页内容
    soup = BeautifulSoup(resp.text, 'html.parser')
    # 定位网页信息
    type_list = soup.find_all('a', href=re.compile('^/typerank'))
    for item in type_list:
        # 获取类型名
        type_name = item.text
        print(type_name)
        # 调用函数,下载电影信息
        download_type(type_name, item['href'])
        time.sleep(3)


def image_movie_image(url, image_name):
    # 使用ip代理
    url1 = 'https://www.kuaidaili.com/free/inha/'
    response = requests.get(url=url1)
    mode = re.compile('(\d+\.\d+\.\d+\.\d+)')
    nums_list = mode.findall(response.text)
    image_save_path = Image_path + os.sep + image_name
    # 请求电信海报所在的网址
    try:
        resp = requests.get(url, proxies={
    
    'ip':nums_list[random.randint(0, len(nums_list) - 1)]})
        with open(image_save_path, 'wb+')as f:
            f.write(resp.content)  # 将海报图片写入文件夹
    except:
        pass


def download_type(type_name, url):
    driver.get(bath_url + url)
    saving_path = save_path + os.sep + type_name + '.csv'
    # 五次拖动页面到最底部动态加载电影信息
    for i in range(5):
        target = driver.find_element(by='id', value='footer')
        driver.execute_script('arguments[0].scrollIntoView();', target)
        time.sleep(1)
    count = 0
    try:
        with open(saving_path, 'a+', newline='') as f:
            csv_f = csv.writer(f)  # 创建一个csv对象
            csv_f.writerow(headers)  # 写入行列标题
            for item in driver.find_elements('xpath', '//div[@class="movie-content"]'):
                try:
                    movie = Movie(type_name)  # 将创建的类实例化为对象
                    # 获取每个对象的属性值
                    movie.url = item.find_element('tag name', 'a').get_attribute('href')
                    movie.name = item.find_element('class name', 'movie-name-text').text
                    movie.img = movie.name + '.jpg'
                    movie.rating = item.find_element(By.CLASS_NAME, 'rating_num').text
                    movie.crew = item.find_element('class name', 'movie-crew').text
                    movie.rank = item.find_element('class name', 'rank-num').text
                    movie.comment = int(re.sub('\D', '', item.find_element('class name', 'comment-num').text))
                    # 使用movie对象的get方法返回其属性,将其属性按行写入csv文件
                    csv_f.writerow(movie.get())
                    # 获取每部电影海报的网址,调用函数,多线程开启下载
                    image_url = item.find_element(by=By.CLASS_NAME, value='movie-img').get_attribute('src')
                    threading.Thread(target=image_movie_image, args=(image_url, movie.img,)).start()
                    # 开启计数,每扒取一部电影次数加一,次数大于20停止该类型电影的扒取
                    count += 1
                    if count > 20:
                        break
                    time.sleep(1)
                except:
                    pass
                finally:
                    print(movie.name, '完成爬取!')
    except Exception as e:
        print(e)

type_url()

笔者并没有将程序完全运行,得到的结果为
在这里插入图片描述
海报:
在这里插入图片描述
电影信息:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_54510474/article/details/121178724