爬虫之豆瓣词云
from urllib import request from bs4 import BeautifulSoup as bs import re import codecs import jieba #分词包 import numpy #numpy计算包 import pandas as pd #分词用到 import matplotlib.pyplot as plt #绘图包 import matplotlib matplotlib.rcParams['figure.figsize'] = (10.0,5.0) from wordcloud import WordCloud #词云包 #爬取豆瓣最受关注图书榜 def gettopchartbook_list(): resp = request.urlopen('https://book.douban.com/chart?subcat=I') html_data = resp.read().decode('utf-8') #转化为BeautifulSoup对象 soup = bs(html_data,'html.parser') #搜索最受关注的图书列表 topchart_book =soup.find_all('ul',class_='chart-dashed-list') #搜索列表中所有图书 topchart_book_list = topchart_book[0].find_all('li',class_='media clearfix') #新建数组用于存放后续的数据 topchart_list = [] #遍历图书馆列表,从中过滤出我们所需的信息 for item in topchart_book_list: #新建字典用于存放我们的图书信息,之后可用class来存储 topchart_dict = {} #搜索到具体信息的位置 book_item = item.find('a',class_='fleft') #得到图书ID topchart_dict['id'] = book_item['href'].split('/')[4] #得到图书名称 topchart_dict['name'] = book_item.getText().replace('\t','').replace('\n','').replace(' ','') #图书名字 #将图书信息加入到数组中 topchart_list.append(topchart_dict) return topchart_list #根据图书ID爬取评论函数 def getCommentbyId(bookId,pageNum): #新建数组用于存放评论信息 eachCommentList = [] if pageNum<0: return False requrl = 'https://book.douban.com/subject/'+ bookId +'/comments/hot'+'?'+'p='+str(pageNum) print(requrl) #爬取热门第一页中的评论信息 resp = request.urlopen(requrl) html_data = resp.read().decode('utf-8') soup = bs(html_data,'html.parser') #搜索到评论所在div comment_div_lits = soup.find_all('div',class_='comment') for item in comment_div_lits: if item.find_all('p')[0].string is not None: eachCommentList.append(item.find_all('p')[0].string) return eachCommentList def main(): #循环获取第一本书的前10页评论 commentList = [] topchartbook_list = gettopchartbook_list() for i in range(10): num = i + 1 commentList_temp = getCommentbyId(topchartbook_list[0]['id'],num) commentList.append(commentList_temp) #为了方便进行数据进行清洗,我们将列表中的数据放在一个字符串数组中 commits = '' for k in range(len(commentList)): commits = commits + (str(commentList[k])).strip() # print(commits) # exit() #可以看到所有的评论已经变成一个字符串了,但我们发现评论中还有不少标点符号等 #这些符号对我们进行词频统计根本就没有用,因此将他们清除,所用的方法是正则表达式 pattern = re.compile(r'[\u4e00-\u9fa5]+') filterdata = re.findall(pattern,commits) cleaned_comments = ''.join(filterdata) # print('评论数组') # print(eachCommentList) # print('评论字符串') # print(commits) # print('去除标点符号的评论') # print(cleaned_comments) # exit() #在这里使用的是结巴分词,如果没有安装结巴分词,可以在控制台用 pip install jieba安装 segment = jieba.lcut(cleaned_comments) # print(segment) # exit() #可以使用pandas库将分词转化成dataframe格式,head()方法只查看前五项内容 words_df = pd.DataFrame({'word':segment}) # print(words_df) # print(words_df.head()) # exit() #可以看到我们的数据中有“我”、“很”等虚词(停用词) #而这些词在任何场景中都是高频时,并且没有实际含义,所以我们要对他们进行清除 #把停用词放在一个stopwords.txt文件中,将我们的数据与停用词进行对比即可 stopwords=pd.read_csv("stopwords.txt",index_col=False,quoting=3,sep="\t",names=['stopword'],encoding='gbk') # print(stopwords) # exit() words_df=words_df[~words_df.word.isin(stopwords.stopword)] # print(words_df.head()) # exit() #接下来进行词频统计 words_stat=words_df.groupby(by=['word'])['word'].agg(['count']) # print(words_stat.head()) #对统计结果进行排序 words_stat=words_stat.reset_index().sort_values(by=["count"],ascending=False) # print(words_stat.head()) #词云展示 wordcloud = WordCloud(font_path="simhei.ttf",background_color="white",max_font_size=80) #指定字体类型、字体大小、背景颜色 word_frequence = {x[0]:x[1] for x in words_stat.head(1000).values} # print(word_frequence) wordcloud = wordcloud.fit_words(word_frequence) # print(wordcloud) # exit() #matplotlib包对图片进行绘制,绘制成功后,返回一个AxesImage对象,要在窗口上显示这个对象,我们可以用show()函数进行 #在某些练习环境下可以省略show()函数,也能自动显示出来 plt.imshow(wordcloud) plt.axis("off") plt.show() wordcloud.to_file('tutorial/Python/images/books/'+str(topchartbook_list[0]['id'])+'.png') #主函数 main()