zoukankan      html  css  js  c++  java
  • python抓取电影<海王>影评词云生成

    海王是前段时间大热的影片,个人对这种动漫题材的电影并不是很感兴趣.然鹅,最近这部电影实在太热了,正好最近看自然语言处理的时候,无意间发现了word cloud这个生成词云的库,还蛮好玩的,那就抓抓这部电影的影评来试试吧.


     

    爬虫抓取豆瓣海王影评

    首先我们登陆豆瓣,进入海王的影评页面.然后打开影评的每一页,看看url有什么特点.

    第一页

    第二页  

    第三页

    还不错,url很规律.

    再开个页面,F12看看,,评论内容在<span class="short">的tag下.

    ok,那就闲话少说,开始抓取吧.requests和BeautifulSoup那是必备的库了,写过爬虫的都知道,贼好用,谁用谁知道.

    comments_counts = 0
    current_url = "https://movie.douban.com/subject/3878007/comments?start=%d&limit=20&sort=new_score&status=P" % (comments_counts)
    while True:
        r=requests.get(current_url)
        print("processing",current_url)
        if r.status_code == 200:
            bs = BeautifulSoup(r.text,"html.parser")
            #print(bs.find_all("span",class_="short"))  
            for comment in bs.find_all("span",class_="short"):
                #print(comment.get_text())
                comments.append(comment.get_text())
        else:
            print(r.status_code,current_url)
            break
    
        comments_counts += 20
        current_url = "https://movie.douban.com/subject/3878007/comments?start=%d&limit=20&sort=new_score&status=P" % (comments_counts)

    爬的过程里,遇到2个问题,本来爬的好好的,爬着爬着都给我返回403了,403是禁止访问啊,尼玛,肯定是豆瓣给反爬了.糟老头子坏得很嘛.

    这时候我们需要把自己的爬虫请求伪装成浏览器请求.F12看一下.选中Network--左侧选中一个url-右侧headers中找到Request headers,其中包含了我们伪装爬虫所需要的信息.

    我们将我们的请求里加上

    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}

    后发现请求还是返回403,再一次尝试加上cookiecookies = {'cookie':'你的cookie'},并且每次访问都sleep 2秒,免得服务器认为我访问太频繁把我ip给封了.此时访问成功了.

    headers = {
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
               ,'Connection': 'keep-alive'
               }
    cookies = {'cookie':'你自己的cookie'}
    
    r=requests.get(current_url,headers=headers,cookies=cookies)

    然后,爬虫就开始开开心心地爬了,爬了N久,还没爬完,果然又采坑了..................

    上面讲到,url很有规律,所以我们每一个url都是拼接出来的,我原先的想法是,如果评论一共200页,那么第201页的url应该是不能访问的.然鹅,即便是没有评论的评论页,也是可以访问的,比如第xx页.......

    再次修改我们的代码

    comments_counts = 0
    current_url = "https://movie.douban.com/subject/3878007/comments?start=%d&limit=20&sort=new_score&status=P" % (comments_counts)
    comments = []
    headers = {
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
               ,'Connection': 'keep-alive'
               }
    cookies = {'cookie':'替换成你自己的cookie'}
    effective = True
    while effective:
        r=requests.get(current_url,headers=headers,cookies=cookies)
        print("processing",current_url)
        effective = False
        if r.status_code == 200:
            bs = BeautifulSoup(r.text,"html.parser")
            #print(bs.find_all("span",class_="short"))  
            for comment in bs.find_all("span",class_="short"):
                #print(comment.get_text())
                comments.append(comment.get_text())
                effective = True
        else:
            print(r.status_code,current_url)
            break
        print(effective)
        comments_counts += 20
        current_url = "https://movie.douban.com/subject/3878007/comments?start=%d&limit=20&sort=new_score&status=P" % (comments_counts)
    
        time.sleep(2) 

     

    好了,到了这里,影评就已经抓取到存到了comments里.

    这一步,我们做分词处理.用大名鼎鼎的jieba分词——一个中文分词库.

    有2点要注意

    • 去除各种标点符号
    • 去除stopwords

    去除标点请参考 https://github.com/fxsjy/jieba/issues/528.通过判断中文编码范围去除标点.

    我是用正则表达式处理的,new_sentence = re.sub(r'[^u4e00-u9fa5]', ' ', old_sentence) 然后再进行分词的, u4e00-u9fa5这个是utf-8中,中文编码的范围

    不过也有说对中文字符而言,不存在确定的范围,建议自己写个标点符号的dict,去做排除.

      Actually, CJK characters are encoded together so there's no critical range for Chinese characters. A punctuation dict could be used to do the filtering.

    幸运的是,通过中文编码范围的方式已经能够解决我的问题了.

    去除stopwords的话要去下载中文的stopwords集.https://github.com/goto456/stopwords

    我们选用"哈工大停用词表".

    开始分词.jieba分词里有3种模式.官方git请戳这里.

    支持三种分词模式:

    • 精确模式,试图将句子最精确地切开,适合文本分析;
    • 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
    • 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分
    # encoding=utf-8
    import jieba
    
    seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
    print("Full Mode: " + "/ ".join(seg_list))  # 全模式
    
    seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
    print("Default Mode: " + "/ ".join(seg_list))  # 精确模式
    
    seg_list = jieba.cut("他来到了网易杭研大厦")  # 默认是精确模式
    print(", ".join(seg_list))
    
    seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")  # 搜索引擎模式
    print(", ".join(seg_list))

    【全模式】: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
    
    【精确模式】: 我/ 来到/ 北京/ 清华大学
    
    【新词识别】:他, 来到, 了, 网易, 杭研, 大厦    (此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了)
    
    【搜索引擎模式】: 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造 

    这里我们采用,精确模式去对我们的影评分词.

    f = open("哈工大停用词表.txt",encoding='utf-8')
    stopword_list = [line.strip() for line in f.readlines()]
    
    new_comments = []
    for comment in comments:
        new_comment = re.sub(r'[^u4e00-u9fa5]', '', comment)  
        new_comments.append(new_comment)
    
    word_list = [word for word in jieba.cut(''.join(new_comments),cut_all=False) if word not in stopword_list]
    print(word_list)

     

    word_list内容如下:
    ['精美绝伦', '水下', '世界', '宏伟', '瑰丽', '海底',.....]

     

    完成了分词以后,我们开始绘制我们的词云.

    我们使用wordcloud. 官方文档https://amueller.github.io/word_cloud/index.html

    在绘图的时候又踩了个坑,中文的词绘制出来全是空的长方形.请参考https://blog.csdn.net/xiemanR/article/details/72796739.

    经过测试发现不支持显示中文的原因是因为wordcloud的默认字体不支持中文,那就好办了,我们设置一种支持中文的字体即可, wordlcloud.WordCloud类初始化函数有个设置字体的参数font_path,把支持中文的字体的路径传给font_path。

    你可以去C:WindowsFonts下找一个自己喜欢的中文字体.右键属性可以看到字体名称.或者你去网上下载自己喜欢的中文字体.

    wordcloud的api用法请参考官方文档的例子.wordcloud的api简单,稍微拿个例子看看改改就能上手.这里就不多说了.我选用了自己的博客头像做背景图样式.

    from wordcloud import WordCloud, ImageColorGenerator
    from scipy.misc import imread
    back_coloring = imread('./background.jpg')  
    print(type(back_coloring))
    #wc = WordCloud(background_color="white", max_words=200, mask=back_coloring,max_font_size=100, random_state=42, width=1000, height=860, margin=2,)
    font='C:WindowsFontssimhei.ttf'
    wc = WordCloud(background_color="black",font_path=font,mask=back_coloring,max_words=2000)
    wc.generate(" ".join(word_list))#注意:传进来的word_list要用空格分隔
    
    import matplotlib.pyplot as plt
    
    # create coloring from image
    image_colors_default = ImageColorGenerator(back_coloring)
    
    plt.figure()
    # recolor wordcloud and show
    plt.imshow(wc, interpolation="bilinear")
    plt.axis("off")
    plt.show()
    
    # save wordcloud
    wc.to_file('./海王_wordcloud.png')

     

     

    大功告成.

     

    完整代码请戳:这里.

  • 相关阅读:
    20135223何伟钦—信息安全系统设计基础第十三周学习总结
    20135223何伟钦—信息安全系统设计基础第十二周学习总结
    20135223何伟钦—信息安全系统设计基础第十一周学习总结
    20135223何伟钦—家庭作业汇总
    20135223何伟钦—信息安全系统设计基础第十周学习总结
    20135223何伟钦—第十章家庭作业
    20135223何伟钦—第六章家庭作业
    20135223何伟钦—信息安全系统设计基础第九周学习总结
    20135223/20135234/20135229小组——亚博 Arduino智能小车实践报告
    20135223何伟钦—信息安全系统设计基础期中总结
  • 原文地址:https://www.cnblogs.com/sdu20112013/p/10193392.html
Copyright © 2011-2022 走看看