Skip to content

Latest commit

 

History

History
344 lines (261 loc) · 10.1 KB

574-2705633-豆瓣电影_分词处理_生成柱形图.sy.md

File metadata and controls

344 lines (261 loc) · 10.1 KB
show version enable_checker
step
1.0
true

爬取图片数据

回忆

  • 上次爬了汉字源
  • 图片不只是可以单独存在
  • 也可以嵌入到网页中的
  • 应该注意到请求头里面可以放东西
  • 爬取的时候可以利用原来网页整体的结构

观察豆瓣电影250

firefox http://movie.douban.com/top250

图片描述

分页爬

# 导包
import requests
from lxml import etree      # 用lxml解析器生成的对象中的xpath方法
from time import sleep
import csv
import numpy as np


# 指定URL
# url = 'https://movie.douban.com/top250'
# 进行UA伪装
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.41'}

# 定义空列表存放电影数据
tiltes_cn = []       # 中文标题
titles_en = []       # 英文标题
links = []           # 详情页链接
director = []        # 导演
actors = []          # 演员
years = []           # 上映年份
nations = []         # 国家和地区
types = []           # 类型
scores = []           # 评分
rating_nums = []      # 评分人数

fp = open('douban_top250.csv','w',encoding='utf-8')
writer = csv.writer(fp)
writer.writerow(['电影中文名', '电影英文名','电影详情页链接','导演','演员','上映年份','国家和地区','类型','评分','评分人数'])

for i in range(0,226,25):
    url = f'https://movie.douban.com/top250?start={i}&filter='
    # 将URL中的参数封装到字典中
    # data = {
    #     'start':i,            # 设置start参数
    #     'filter':'',
    # }
    # 发起请求,获取网页响应
    response = requests.get(url,headers=headers
                            # ,data=data
                           )
    sleep(1)
    # print(response.status_code)
    # print(response.encoding)
    # print(response.text)
    
    # 获取响应内容
    html = response.text  
    # 实例化一个etree对象
    data = etree.HTML(html)
    
    # 所有电影信息都在li标签下,所以我们可以先定位到li标签,在通过循环获取每一个li标签中的信息
    li_list = data.xpath('//*[@id="content"]/div/div[1]/ol/li')
    # 通过循环遍历每一页中的所有li标签,获取该页面所有电影的数据
    for each in li_list:
        # 中文标题
        title1 = each.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0] 
        tiltes_cn.append(title1)
        
        # 英文标题
        # 每次获取到的数据存在一个列表中,通过下标索引取列表的值
        # 通过字符串的strip()方法去除字符串首尾的指定字符串
        title2 = each.xpath('./div/div[2]/div[1]/a/span[2]/text()')[0].strip('\xa0/\xa0')
        titles_en.append(title2)
        
        # 链接
        link = each.xpath('./div/div[2]/div[1]/a/@href')[0]     
        links.append(link)
        
        # 导演、主演
        info1 = each.xpath('./div/div[2]/div[2]/p[1]/text()[1]')[0].strip()       # 通过strip方法去除字符串的前后空格
        split_info1 = info1.split('\xa0\xa0\xa0')      # 通过指定字符串分割字符串
        dirt = split_info1[0].strip('导演: ')
        director.append(dirt)
        # 有些电影的主演为空,所以需要进行条件判断
        # 如果导演和主演信息都有,则获取主演信息
        if len(split_info1) == 2:
            ac = split_info1[1].strip('主演: ')
            actors.append(ac)
        # 如果没有主演信息,则将其信息设置为空
        else:
            actors.append(np.nan)
        
        # 年份、国籍、类型
        info2 = each.xpath('./div/div[2]/div[2]/p[1]/text()[2]')[0].strip()    # 去除字符串首尾的空格
        split_info2 = info2.split('\xa0/\xa0')    # 通过字符串分割获取字符串中的年份、国籍和类型
        # print(split_info)
        year = split_info2[0]
        nation = split_info2[1]
        ftype = split_info2[2]
        years.append(year)
        nations.append(nation)
        types.append(ftype)
        
        # 电影评分
        score = each.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
        scores.append(score)
        
        # 获取电影打分人数
        num = each.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0].strip('人评价')
        rating_nums.append(num)
        
        writer.writerow([title1,title2,link,dirt,ac,year,nation,ftype,score,num])
    print(f'————————————第{int((i/25)+1)}页爬取完毕!——————————————')
        
        
    
fp.close()   # 写入完成后,关闭文件
print('——————————————————————————————————爬虫结束!!!!!————————————————————————————————————————————————')

观察结果

sudo apt install csvtool
  • 安装后观察国别
csvtool col 1,7 douban_top250.csv
  • 效果

图片描述

  • 评分谁最高?谁最低?

评分

import pandas as pd

df = pd.read_csv('douban_top250.csv', sep=",")

score = df['评分'].max()
print("最高评分的电影是:", df[df['评分'] == score]['电影中文名'].iloc[0], "\t分数是:", score)
score = df['评分'].min()
print("最低评分的电影是:", df[df['评分'] == score]['电影中文名'].iloc[0], "\t分数是:", score)
  • 评分高低

图片描述

  • 评分人数
    • 谁高谁低?

评分人数

import pandas as pd

df = pd.read_csv('douban_top250.csv', sep=",")

num = df['评分人数'].max()
print("最多人评分的电影是:", df[df['评分人数'] == num]['电影中文名'].iloc[0], "\t人数是:", num)
num = df['评分人数'].min()
print("最少人评分的电影是:", df[df['评分人数'] == num]['电影中文名'].iloc[0], "\t人数是:", num)
  • 评分人数

图片描述

  • 各种类型
    • 谁多谁少?

安装类库

  • 安装词云和分词包
pip3 install wordcloud
pip3 install jieba

类型

import pandas as pd
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import jieba
import csv

def segment(text):
    for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~,。?!:;”“’‘-=《》()、【】↓LO':
        text = text.replace(ch, " ")
    words_list_jieba = jieba.lcut(text)
    words_list = []
    for i in words_list_jieba:
        words_list.append(i)
    return words_list

def words_frequency(words_list):
    words_dict = {}
    for key in words_list:
        words_dict[key] = words_dict.get(key, 0) + 1
    return words_dict

def words_dict_sort(words_dict, descending):
    temp_dict = sorted(words_dict.items(), key=lambda x: x[1], reverse=descending)
    return temp_dict

df = pd.read_csv('douban_top250.csv', sep=",")
text = ' '.join(df['类型'].dropna())
words_list = segment(text)
words_dict = words_frequency(words_list)
print(words_dict)
  1. 将标点替换为空格
  2. 将字符串分词生成词列表
  3. 将词列表生成词频字典
  4. 将词频字典输出

图片描述

结果

  • 结果可以生成
    • 柱饼折
    • 词云图

图片描述

  • 想要得到
    • 关于国家和地区的
    • 词频字典

数据清洗

  • 如果想要将一些词汇
    • 从结果中清洗呢?
import pandas as pd
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import jieba
import csv

def segment(text):
    for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~,。?!:;”“’‘-=《》()\n【】↓LO':
        text = text.replace(ch, " ")
    words_list_jieba = jieba.lcut(text)
    words_list = []
    for i in words_list_jieba:
        if i in ["你", "UNG", "她", "三娘", "这位", "微博", "视角", "0", "秀英", "很", "热词", "两会", "看","这些", "聊", "我们", "关于", "要", "视频", "这", "那", "有", "不", "在", "却", "都","就", "是", "就是", "我", "他", "它", "他们","它们", "的", "着", "了", "和", "与", "个", "一个", "一","《", "》", " ", "\n"] or i.isnumeric():
            pass
        else:
            words_list.append(i)
    return words_list

def words_frequency(words_list):
    words_dict = {}
    for key in words_list:
        words_dict[key] = words_dict.get(key, 0) + 1
    return words_dict

def words_dict_sort(words_dict, descending):
    temp_dict = sorted(words_dict.items(), key=lambda x: x[1], reverse=descending)
    return temp_dict

df = pd.read_csv('douban_top250.csv', sep=",")

text = ' '.join(df['国家和地区'].dropna())
words_list = segment(text)
words_dict = words_frequency(words_list)
wordcloud = WordCloud(font_path="/usr/share/fonts/truetype/wqy-zenhei.ttc",  # 为显示正确的中文,需指定字体
                      background_color="white",  # 背景颜色
                      collocations=False,
                      width=800,
                      height=600,
                      margin=2,  # 设置图片默认的大小
                      ).fit_words(words_dict)
wordcloud.to_file('nation.png')

  • 可以把某些单词
    • 排除

最终结果

  • 首先声明
    • 香港地区、澳门地区、台湾地区是
    • 中国不可分割的一部分

图片描述

  • 如果想要将
    • 中国大陆、中国香港、中国台湾
    • 作为地区 分类统计

添加词汇

  • 将三个单词加入字典词条
jieba.add_word("中国大陆", freq=None, tag=None)
jieba.add_word("中国台湾", freq=None, tag=None)
jieba.add_word("中国香港", freq=None, tag=None)
  • 结果

图片描述

  • 期待祖国第八艺术和第九艺术起飞

总结

  • 豆瓣爬完了
  • 还能爬点什么呢?🤔
  • 下次再说