weixin_46142002 2021-06-13 19:05 采纳率: 0%
浏览 161

IndexError: list index out of range

import time
import jieba
from snownlp import SnowNLP
import requests
from bs4 import BeautifulSoup
from wordcloud import WordCloud
from PIL import Image
import numpy as np


# 此函数实现爬取豆瓣top250总榜单
def top_spider():
    for i in range(0, 250, 25):
        num = str(i)
        headers = {
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/76.0.3809.132 Safari/537.36 '
        }   # 请求头模拟真人访问
        url1 = 'https://movie.douban.com/top250?start='
        url2 = '&filter='
        url = url1 + num + url2  # 拼接,形成完整的链接
        time.sleep(1)  # 调用sleep(),令每轮爬取之间暂停一点时间,防止被豆瓣逮住
        req = requests.get(url, headers=headers)  # requests的get方法爬取
        html = req.text
        bs = BeautifulSoup(html, 'lxml')   # 将爬取的数据放入‘美丽汤’
        texts1 = list(bs.findAll('div', class_="pic"))     # 获取所有<div class="pic"></div>标签的内容,此标签存储了所有排名
        texts2 = list(bs.findAll('div', class_='hd'))      # 获取所有<div class="hd"></div>标签的内容,此标签存储了所有电影名
        texts3 = list(bs.findAll('span', class_='title'))  # 获取所有<span class="title"></span>标签的内容,此标签存储了所有电影的单独页面链接
        new_rank, new_name, new_m_url = [], [], []         # 创建空列表,存储每一轮得到的电影排行、电影名和单独页面链接
        for j in texts1:
            rank = str(j).split('<em class="">')[1].split('<')   # 筛选掉多余内容,只留下排行的数字
            rank = 'top' + str(rank[0])
            new_rank.append(rank)
        for k in texts3:
            cut = str(k).replace('<span class="title">', '').replace('</span>', '')   # 筛选掉多余内容,只留下电影的名称
            # 外国电影有外文原名,这里我们就不记录了,将其筛掉
            if cut[0] != ' ':
                new_name.append(cut)

        for u in texts2:
            mu = str(u).split('href="')[1].split('">')   # 筛选掉多余内容,只留下单独页面的链接
            mu = str(mu[0])
            new_m_url.append(mu)

        for h in range(0,25):
            total.append(new_rank[h] + ' ' + new_name[h] + ' ' + new_m_url[h] + '\n')  # 将排行、电影名和链接,按行放入total[]中
            with open('Top.txt', 'a', encoding='utf-8') as r:
                r.write(new_rank[h] + ' ' + new_name[h] + ' ' + new_m_url[h] + '\n')   # 写入.txt文件
                r.close()

        time.sleep(1)
        s = (i / 25) + 1
        print("已写入Top.txt中")
        print('第' + str(s) + '轮榜单爬取完成')

# 此函数实现爬取一个排名为top(用户输入)的电影的全部热门短评
def short_spider(top):
    dtop = int(top) - 1
    comment = str(total[dtop]).split()     # comment是分割total[]后,存储了一行 排行、电影名和链接 的列表
    print('正在爬取电影:' + str(comment[1]) + ' 的短评......')
    f_url = comment[2] + 'comments?'       # 拼接,形成显示全部短评的页面的链接的前半部分
    for i in range(0, 240, 20):
        if i < 20:
            num = ''
        else:
            num = 'start=' + str(i)

        headers = {
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/76.0.3809.132 Safari/537.36 '
        }

        f_url2 = '&limit=20&status=P&sort=new_score'
        url = f_url + num + f_url2     # 拼接,形成完整的显示全部短评的页面的链接
        time.sleep(1)
        req = requests.get(url, headers=headers)    # requests的get方法爬取
        html = req.text
        bs = BeautifulSoup(html, 'lxml')            # 放入’美丽汤‘
        texts = list(bs.findAll('span', class_="short"))    # 获得所有<span class="short"></span>标签的内容

        for n in texts:
            shortP = str(n).replace('<span class="short">', '').replace('</span>', '')    # 筛选出短评文字
            shortQ = SnowNLP(shortP)     # 用snowNLP库,进行简单的中文情感分析,
            a = '情感分析:'
            if shortQ.sentiments > 0.6000:   # snowNLP分析出来一个数字,越接近1,越有可能是正面情感;越接近0,越有可能是负面情感
                b = '可能为正面情感'
            else:
                b = '可能为负面情感'
            filename = '短评.txt'
            with open(filename, 'a', encoding='utf-8') as r:
                r.write(shortP + '\n')
                r.write(a + b + '\n\n')
                r.close()

        print(str(comment[1]) + ' 的短评已写入文件中!')
        p = (i / 20) + 1
        print('第' + str(p) + '轮短评爬取完成')
        time.sleep(1)


# 此函数实现将爬取的短评进行简单的情感分析;然后分词,统计高频词;利用高频词,制作出词云
def main_wordcloud():
    # 统计词频
    filename = open('短评.txt', 'r', encoding='utf-8')
    s = filename.read()    # 读取短评文件
    words = jieba.cut(s, cut_all=False)   # 使用jieba进行分词
    word_dict = {}  # word_list用于保存每个词语及其频率
    word_list = ''  # word_list用于保存jieba分出来的全部词语,用于词云制作
    for word in words:
        # 不统计一个字的词,和情感分析的固定词
        if len(word) > 1 and word != '情感' and word != '正面' and word != '可能' and word != '分析' and word != '负面':
            word_list = word_list + ' ' + word   # 保存进word_list中
            if word_dict.get(word):
                word_dict[word] = word_dict[word] + 1   # 保存进word_dict中,每有重复的,频率+1
            else:
                word_dict[word] = 1

    # 按频率进行排序
    sort_words = sorted(word_dict.items(), key=lambda x: x[1], reverse=True)
    print('高频词如下:')
    print(sort_words[0:101])  # 输出频率前0-100的词
    # 创建一个词云对象
    # 讀取欲做掩膜的圖片
    mask = np.array(Image.open(r"C:\Users\Yeerealrainstar\Desktop\papa\tree.jpg"))
    wc = WordCloud(
        background_color="white",  # 背景颜色白色
        font_path="C:\Windows\Fonts\FZSTK.TTF",  # 使用系统自带的中文字体
        mask=mask,max_words=4000
    )
    wc.generate(word_list)
    wc.to_file("WorldCloud.png")  # 保存词云图像
    print('词云已绘制完成,图片保存在项目根目录')


total = []  # 存储榜单信息
top_spider()
top = input('请输入你想爬取的电影的排名,之后会爬取其短评:')
print('开始爬取短评。')
short_spider(top)
main_wordcloud()
  • 写回答

4条回答 默认 最新

  • CSDN专家-HGJ 2021-06-13 19:42
    关注

    代码没有问题的,可能是请求过去频繁了,一些数据没有返回结果,将间隔时间设长些试试。

    评论

报告相同问题?

悬赏问题

  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误