栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

xpath爬取豆瓣电影Top250的基本信息

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

xpath爬取豆瓣电影Top250的基本信息

import pymysql
import time
import pandas as pd
from lxml import etree
import requests
import re

# 定义一个全局列表变量,用于存放爬取豆瓣电影Top250的信息
allTopMovieList = []


# 封装解析HTML页面和数据爬取的方法
def getParse(url):

    # 打印提示信息
    print('正在爬取豆瓣电影Top250的信息......')

    # 定义一个请求头
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                             "Chrome/92.0.4515.159 Safari/537.36"}

    # 构造一个请求对象,并通过get函数发送HTTP请求,最后将响应结果保存于response对象中
    html = requests.get(url=url, headers=headers).text

    # 解析HTML页面
    selector = etree.HTML(html)

    # 获取到一部电影的基本信息
    lis = selector.xpath('//*[@id="content"]/div/div[1]/ol/li')

    for oneSelector in lis:

        # 获取豆瓣电影Top250排名
        movie_ranking = oneSelector.xpath('./div/div[1]/em/text()')[0]

        # 获取豆瓣电影Top250名称
        movie_name = oneSelector.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]

        # 获取豆瓣电影Top250的评分
        movie_score = oneSelector.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]

        # 获取豆瓣电影Top250的评介人数
        movie_number = oneSelector.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
        movie_number = re.sub(r'D', "", movie_number)

        # 获取豆瓣电影Top250的主演和导演
        movie_director_starring = oneSelector.xpath('./div/div[2]/div[2]/p[1]/text()')[0]

        # python的split()方法:通过指定分隔符对字符串进行切片
        # 以Tab键分割movie_director_starring
        movie_director_starring_str = movie_director_starring.split('   ')[-1]
        movie_director_starring_list = movie_director_starring_str.split(':')

        # re.sub(pattern, repl, string, count=0, flags=0):用于替换字符串中的匹配项,返回替换后的值
        # 获取豆瓣电影Top250的导演
        movie_director = re.sub(r's', ' ', movie_director_starring_list[1]).split('主演')[0]
        movie_director = re.sub('&(.*)', '', movie_director)
        # 匹配字符串的开头与末尾有空格子字符,替换为空
        movie_director = re.sub('   $', '', re.sub('^ ', '', movie_director))
        movie_director = re.sub(r'.', '', movie_director)
        movie_director = re.sub('   ', '', movie_director)

        # 获取豆瓣电影Top250主演
        # 判断是否有主演
        if len(movie_director_starring_list) == 3:

            # 用正则表达式处理电影的主演
            movie_starring = re.sub(r'.', '', movie_director_starring_list[-1])
            movie_starring = re.sub(r's', ' ', movie_starring)  # 's':匹配任何空白字符,包括空格、制表符、换页符等等
            movie_starring = re.sub('&(.*)', '', movie_starring)
            movie_starring = re.sub(' ', '', movie_starring)
            movie_starring = re.sub(''', '', movie_starring)
            movie_starring = re.sub(r' ', '', movie_starring)

        else:

            # 如果没有主演就设置为空
            movie_starring = 'null'

        # 获取到豆瓣电影Top250的上映年份、制片国家/地区、类型
        movie_YCT = oneSelector.xpath('./div/div[2]/div[2]/p[1]/text()')[1]

        # 用斜杆来分割上映年份、制片国家/地区、类型
        movie_YCT_list = movie_YCT.split('/')

        # 获取电影的上映年份 'D':匹配一个非数字字符
        movie_releaseDate = re.sub(r'D', '', movie_YCT_list[0])

        # 获取豆瓣电影Top250的制片国家 / 地区; 's':匹配任何空白字符,包括空格、制表符、换页符等
        movie_country = re.sub(r's', ' ', movie_YCT_list[1])
        # 匹配字符串的开头与末尾有空格子字符,替换为空
        movie_country = re.sub(' $', '', re.sub('^ ', '', movie_country))

        # 获取豆瓣电影Top250的类型
        movie_type = re.sub(r's', ' ', movie_YCT_list[-1].split('n')[0]).split(' ')[1:]
        # 将列表转换为字符串,其中一'/'来分割字段
        movie_type = '/'.join(movie_type)

        # append()方法:用于在列表末尾添加新的对象
        # 将爬取到的一条电影数据存放到oneMoviesList列表中
        oneMoviesList = [
            movie_ranking,  # 排名
            movie_name,  # 电影名称
            movie_director,  # 导演
            movie_type,  # 电影类型
            movie_releaseDate,  # 电影上映时间
            movie_score,  # 电影评分
            movie_number,  # 批评人数
            movie_starring,  # 主演
            movie_country  # 上映国家
        ]

        # 打印每部电影信息
        # print(oneMoviesList)

        # 再将oneMoviesList列表中的数据存放到allTopMovieList列表中
        allTopMovieList.append(oneMoviesList)


def getURLS():

    # 定义一个urls列表,用于存放豆瓣电影Top250的url
    urls = []

    # 观察豆瓣电影Top250的网址如下:
    # 第1页:https://movie.douban.com/top250?start=0&filter=
    # 第2页:https://movie.douban.com/top250?start=25&filter=
    # ..................
    # 最后一页:https://movie.douban.com/top250?start=225&filter=
    # 则可以总结一下规律:
    # 第i页的网址:'https://movie.douban.com/top250?start={}&filter='.format(i)
    # 获取每一页的url,并将其存放到urls列表中

    for i in range(0, 256, 25):

        url = 'https://movie.douban.com/top250?start={}&filter='.format(i)

        urls.append(url)

    return urls


def saveCSVData(data):

    # 将数据保存到.csv文件
    data.to_csv("./top250.csv", index=False, mode="w", encoding="utf-8")


def saveJSONData(data):

    # 将数据保存到.json文件
    data.to_json('./top250.json', orient="records", force_ascii=False)


# 将列表格式的数据转换为Pandas支持的Dataframe
def dataFormatConversion():

    # 设定一个列标签
    column = [
        'movie_rank',
        'movie_name',
        'movie_director',
        'movie_type',
        'movie_release_date',
        'movie_score',
        'movie_number_people',
        'movie_starring',
        'movie_country'
    ]

    # 调用Dataframe方法
    df = pd.Dataframe(allTopMovieList, columns=column)
    return df


# 将电影信息保存到MySQL数据库中
def saveMysqlData(user, password, database):

    # 连接MySQL服务器
    db = pymysql.connect(host="localhost", user=user, password=password, database=database)

    # 使用cursor()方法获取操作游标
    cursor = db.cursor()

    # SQL 插入语句
    for one in allTopMovieList:

        sql = '''
            insert into t_movie(
                movie_rank,
                movie_name,
                movie_director,
                movie_type,
                movie_release_date,
                movie_score,
                movie_number_people,
                movie_starring,
                movie_country
            ) values (%d,'%s','%s','%s','%s',%f,%d,'%s','%s')
            ''' % (int(one[0]), one[1], one[2], one[3], one[4], float(one[5]), int(one[6]), one[7], one[8])

        try:

            # 执行sql语句
            cursor.execute(sql)
            # 提交到数据库执行
            db.commit()

        except Exception as e:
            # 打印报错信息
            print(repr(e))
            # 如果发生错误则回滚
            db.rollback()

    # 关闭数据库连接
    db.close()


# 创建存储movie信息的t_movie表
def createMovieTable(user, password, database):

    # 打开数据库连接
    db = pymysql.connect(host="localhost", user=user, password=password, database=database)

    # 使用cursor()方法获取操作游标
    cursor = db.cursor()

    # 使用 execute() 方法执行 SQL,如果表存在则删除
    cursor.execute("DROP TABLE IF EXISTS t_movie")

    # 创建t_movie表
    sql = '''
        create table t_movie(
            movie_rank int,
            movie_name varchar(255),
            movie_director varchar(255),
            movie_type varchar(255),
            movie_release_date varchar(50),
            movie_score float,
            movie_number_people int,
            movie_starring varchar(255),
            movie_country varchar(255)
        )character set utf8;
        '''

    try:

        # 执行sql语句
        cursor.execute(sql)
        # 提交到数据库执行
        db.commit()

    except Exception as e:

        # 打印错误信息
        print(repr(e))
        # 如果发生错误则回滚
        db.rollback()

    # 关闭数据库连接
    db.close()


if __name__ == '__main__':

    # 标记一个开始时间
    start_time = time.process_time()

    # 获取得豆瓣电影Top250的url列表
    urls = getURLS()

    print('{:=^50}'.format('开始爬取豆瓣电影信息'))

    # 遍历urls列表
    for url in urls:
        # 调用getParse(url)方法,进行电影信息的爬取
        getParse(url)

    # 将列表格式的数据转换为Pandas支持的Dataframe
    data = dataFormatConversion()

    # 将数据保存为csv文件
    saveCSVData(data)

    # 将数据保存为json文件
    saveJSONData(data)

    # mysql 用户与密码,连接的mysql的数据库名
    user = 'root'
    password = 'root'
    database = 'movie_db'

    # 创建表t_movie,用于存放电影信息
    createMovieTable(user, password, database)

    # 保存电影信息
    saveMysqlData(user, password, database)

    # 标记一个结束时间
    end_time = time.process_time()

    # 打印结束提示信息
    print('{:=^50}'.format('爬取结束'))
    print("爬取豆瓣电影Top250信息的总时间:{} n总共爬取豆瓣电影Top250信息的条数:{}".format(end_time - start_time, len(allTopMovieList)))

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/326481.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号