牛刀小试-《你好,李焕英》影评词云

大数据 数据可视化
最近,贾玲导演的电影《你好,李焕英》在春节档一众电影中脱颖而出,成为了一匹黑马,更是中国影史上第三部票房破50亿的电影。我们从豆瓣上看到,该影片当前评分是8.1分,接近30%的评价都是5颗星。今天我们就来从豆瓣上爬取一部分影评,结合jieba和pyecharts做个分词和词云图。

 最近,贾玲导演的电影《你好,李焕英》在春节档一众电影中脱颖而出,成为了一匹黑马,更是中国影史上第三部票房破50亿的电影。


我们从豆瓣上看到,该影片当前评分是8.1分,接近30%的评价都是5颗星。今天我们就来从豆瓣上爬取一部分影评,结合jieba和pyecharts做个分词和词云图。


打开开发者工具

首先,在豆瓣上找到电影《你好,李焕英》,下拉到影评区,可以看到共有三十多万条短评和七千多影评。短评数量太多了,我们还是数量较少的影评下手吧。接下来,在浏览器中按F12或者右键点击检查打开开发者工具,然后选择network(网络)选项,然后点击上图中影评区的“全部7494条”,就可以在开发者工具中看到一系列的请求。


寻找目标URL


将影评区拖到最底部,将会看到影评被分成来几百个页面,然后我们清空开发者工具中的捕获的请求,点击下一页,在请求列表中找到第一条,这就是我们翻页的通用请求了:每页20条,使用start参数判断起始位置,这样循环300多次就可以获取到全部的影评了。

等等,貌似还少了什么?由于影评内容较长,评论只显示了一部分,要想看到全部内容,还需要点击一下展开全文。

点一下展开,发现浏览器发出一条这样的请求,刚好返回的json就是完整的评论内容。依次点击后面的几条影评,也都是同样格式的请求,只有full前面的数字发生了变化,可以断定这串数字就是这条影评的id了。那么如何知道每一条影评的id是什么呢?

检查目标元素

鼠标放到展开按钮上,右键点击检查元素,我们可以发现,页面上的每一条影评都对应了一个div,这个div有一个data-cid的参数,它的值刚好就是上面我们请求中的id,所以我们只要在每次请求页面时,遍历review-list中所有的div,获取到data-cid的值,再把影评id循环代入到上面的url中请求完整影评内容即可。

爬取完影评评论并保存到本地,然后使用jieba分词将评论文章分割成单词,然后去除停用词并统计词频。

大功告成

最后一步就是利用我们前面提到的pyecharts中的wordcloud来制作词云了。选择一张照片作为词云的形状,然后导入单词及其词频作为权重,输出文件即可。

 

(图片来源于网络,侵删)

详细代码:

  1. import requests 
  2. import random, time, json 
  3. from bs4 import BeautifulSoup as bs 
  4. import jieba 
  5. import pandas as pd 
  6. from pyecharts import charts, options 
  7.  
  8. url1 = 'https://movie.douban.com/subject/34841067/reviews?start={}' 
  9. url2 = 'https://movie.douban.com/j/review/{}/full' 
  10. header = '''Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 
  11. Accept-Encoding: gzip, deflate, br 
  12. Accept-Language: zh-CN,zh;q=0.9 
  13. Connection: keep-alive 
  14. Cookie: bid=RWSCuDu3-hA; douban-fav-remind=1; __gads=ID=f22d1fef6a644a7a-228e1b3a32c50048:T=1607935481:RT=1607935481:S=ALNI_MZwRU5qCsyehoDFgRdf7D5PRBqqCg; ll="108288"; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1614764251%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DlzDNd94NFnBQCDIqNI00Il5NwjZoARpWz1lQy5MGKdL26rV5yrb1N1HIoGzoKu5k%26wd%3D%26eqid%3Dda5556d4000016f000000003603f58d7%22%5D; ap_v=0,6.0; __utmc=30149280; __utmz=30149280.1614764252.6.6.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utma=223695111.1843127241.1614764252.1614764252.1614764252.1; __utmc=223695111; __utmz=223695111.1614764252.1.1.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __yadk_uid=rcNjENFDHY62mSmlZqJtXPKJZUfQkM75; _vwo_uuid_v2=D771633F1FBA119FD38FD79DCE082F26D|35b2c7beff079fe25b62163affe94ce8; _pk_id.100001.4cf6=2e0a301ce93b85e0.1614764251.1.1614764408.1614764251.; __utma=30149280.1170719909.1607935481.1614764252.1614766647.7; __utmt=1; __utmb=30149280.2.9.1614766647; dbcl2="152966201:ETujHWfkU2g"; ck=1WtR 
  15. Host: movie.douban.com 
  16. Referer: https://accounts.douban.com/ 
  17. Sec-Fetch-Dest: document 
  18. Sec-Fetch-Mode: navigate 
  19. Sec-Fetch-Site: same-site 
  20. Sec-Fetch-User: ?1 
  21. Upgrade-Insecure-Requests: 1 
  22. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36''
  23. headers = {x.split(': ')[0]: x.split(': ')[1] for x in header.split('\n')} 
  24. session = requests.session() 
  25. session.headers = headers 
  26. result1 = [] 
  27. for i in range(0, 365): 
  28.     print(i) 
  29.     try: 
  30.         r = session.get(url1.format(i)) 
  31.         r.close() 
  32.         content = bs(r.text) 
  33.         result1.extend(x.get('data-cid'for x in content.select('div.review-list > div')) 
  34.     except
  35.         pass 
  36.     time.sleep(random.randrange(3, 20)) 
  37.  
  38. result2 = [] 
  39. for j in result1: 
  40.     print(result1.index(j)) 
  41.     try: 
  42.         r = session.get(url2.format(j)) 
  43.         r.close() 
  44.         data = json.loads(r.text) 
  45.         result2.append(data) 
  46.     except
  47.         pass 
  48.     time.sleep(random.randrange(10, 20)) 
  49.  
  50. review = [] 
  51. for i in result2: 
  52.     html = bs(i['html']) 
  53.     review.append(html.text) 
  54. for i in ['贾玲''贾晓玲''沈腾''张小斐''李焕英''光林''陈赫''沈光林''冷特']: 
  55.     jieba.add_word(i) 
  56. words = [] 
  57. for x in review: 
  58.     cut = jieba.lcut(x) 
  59.     words.extend(cut) 
  60.  
  61. with open('stopwords.txt''r')as f: 
  62.     stop = [x.strip() for x in f.readlines()] 
  63.     f.close() 
  64. df = pd.DataFrame(words, columns=['words']) 
  65. df_count = pd.DataFrame(df.groupby('words').size()) 
  66. count = df_count.loc[[x for x in df_count.index.values if x not in stop]].sort_values(0, ascending=False
  67. cloud = charts.WordCloud(init_opts=options.InitOpts(width='2000px', height='2000px')) 
  68. cloud.add('你好,李焕英'
  69.           data_pair=[(x, count.loc[x].values[0] / 100) for x in count.index.values], 
  70.           mask_image='jialing.jpeg'
  71.           word_size_range=[10, 300]) 
  72. cloud.render('你好李焕英.html'

 

责任编辑:姜华 来源: 数师兄
相关推荐

2014-06-06 13:42:26

iOS 8QR CodeWWDC2014

2012-05-03 10:24:02

ApacheMINAJava

2010-03-05 17:25:07

sharepoint

2011-11-30 16:02:13

笔记本评测

2017-04-11 20:49:02

机器学习大数据数据分析

2021-03-11 09:30:19

互联网数据技术

2021-03-04 09:35:15

电影腾讯微视

2014-12-16 15:10:32

APC BR1000G后备式UPS电源

2021-01-08 09:07:19

Scrapy框架爬虫

2017-05-04 21:15:30

Android分辨率

2012-02-24 10:48:56

语盒开源

2023-10-07 08:59:02

2021-05-20 07:56:35

Bean容器Spring

2022-07-04 23:24:28

sql优化监控

2018-08-02 14:12:16

影评分析狄仁杰之四大天王

2018-01-01 23:02:56

2012-11-09 16:51:41

阿里云开发者开发

2023-04-20 17:41:38

开源清华

2011-09-23 14:24:58

惠普云计算李艾科

2021-05-04 22:31:15

零信任网络安全网络攻击
点赞
收藏

51CTO技术栈公众号