目录
一、回顾爬虫
1、什么是爬虫
爬虫是一种自动化程序,用于在互联网上抓取、提取和分析网页数据。它通过模拟人类用户的行为,访问网页并提取所需的信息,然后将这些信息保存或使用于其他目的。爬虫可以自动化地访问大量网页,并将提取到的数据用于搜索引擎索引、数据分析、舆情监控等各种应用场景。
2、实操爬虫
1)寻找标签位置
2)爬取苏某某购产品好评数据
from selenium import webdriver # 导入浏览器驱动
from selenium.webdriver.common.by import By # 导入驱动中的方法,用来选择定位标签的方式
# 获取需要的网页的url地址
url = "https://review.suning.com/cluster_cmmdty_review/cluster-38249278-000000012389328846-0000000000-1-good.htm?originalCmmdtyType=general&safp=d488778a.10004.loverRight.166"
driver = webdriver.Edge() # 打开驱动,运行浏览器,用于自动化模拟真人操作
driver.get(url) # 使用驱动发送请求,参数为请求的网址,获取到的数据全部存放在驱动中
driver.refresh() # 用于在点击下一页的时候刷新页面
file = open('1.txt','w',encoding='utf8') # 创建并打开一个文件,用于存放爬取到的好评数据
while True: # 创建一个死循环,用于点击下一页按钮后再次进行页面爬取
li_hp = driver.find_elements(By.XPATH, '//div[@class="rv-target-item"]/div') # 获取页面中所有的评价用户标签,返回的是一个列表,包含每个标签的信息
print(li_hp)
for li in li_hp: # 遍历每一个用户的标签
hp = li.find_element(By.XPATH,'div//div[@class="topic-body"]/p').text # 使用属性定位,直接到p标签下,p标签下存放的是评论内容,使用text返回所有文本内容
# print(hp)
file.write(hp) # 将所有的评论写入文件
next = driver.find_element(By.XPATH,'//a[@class="next rv-maidian "]') # 此处为定位到下一页按钮的标签位置
if not next: # 判断是否有按钮标签,没有按钮标签的话则会直接结束循环
break
else:
next.click() # 有按钮标签,那么使用click点击标签
运行代码:
此时好评文件1.txt内的内容为:(我只爬取了3000条就中断了循环)
3)爬取差评内容
只需要将上述代码再复制一遍,然后将其中的URL更改为下列链接即可
URL = "https://review.suning.com/cluster_cmmdty_review/cluster-38249278-000000012389328846-0000000000-1-bad.htm?originalCmmdtyType=general&safp=d488778a.10004.loverRight.166"
此处讲解同上,差评的文件存放在名为2.txt下
内容如下:此处手动增加了一行名为content,用于后期将文件转换成DateFrame格式
二、数据分词
1、将获取到的好评和差评数据进行初步分词
1)初步分词
import pandas as pd
cp_content = pd.read_table(r'.\2.txt',encoding='utf8') # 导入差评文件,将其转变为DF文件,列名为手动填入的content
yzpj_content = pd.read_table(r".\1.txt",encoding='utf8') # 导入优质评价,将其转变为DF文件,列名为手动填入的content
# 差评分词
import jieba # 导入分词库
cp_seqments = [] # 建立一个空列表用于存放分词过后的差评的词组
contents = cp_content.content.values.tolist() # 将差评的DF数据的列中的值转变为列表形式,content为列号,values为列中的值,tolist是转变为列表形式
for content in contents: # 遍历列表中的每一条评论
results = jieba.lcut(content) # 对每一条评论进行分词
if len(results) >1: # 如果分出来的词组长度大于1,那么将其增加到列表中
cp_seqments.append(results)
cp_fc_results = pd.DataFrame({'content':cp_seqments}) # 将差评的数据转变为DF类型,并设置列名为content,每一行为每条评论分词的所有词组
cp_fc_results.to_excel('cp_fc_results.xlsx',index=False) # 将差评DF数据保存为excel类型文件,并设置数据中不含行索引,其中同样是列名为content,每一条数据为每个用户的评价分词词组
# 优质评价分词
yzpj_segments = [] # 同样的,设置一个空列表,用于存放分词后的好评数据的词组
contents = yzpj_content.content.values.tolist() # 将每一条好评DF数据转变成列表形式
for content in contents: # 遍历每一条好评数据,对其进行分词
results = jieba.lcut(content)
if len(results)>1: # 判断分出来的词组长度是否大于1,用于去除大量的标点符号分词等无用词组
yzpj_segments.append(results)
yzpj_fc_results = pd.DataFrame({'content':yzpj_segments}) # 将词组数据转变为DF类型
yzpj_fc_results.to_excel('yzpj_fc_results.xlsx',index=False) # 将每个用户的好评的词组保存为Excel格式,一行代表一个用户的评价词组
得到两个excel文件
2)内容如下:
2、导入停用词词库
1)导入停用词库后对上述词组进行处理
# 以DF类型导入停用词,并设置内部解释器为python类型
stopwords = pd.read_csv(r'.\红楼梦\StopwordsCN.txt',encoding='utf8',engine='python',index_col=False)
# 定义去除停用词函数
def drop_stopwords(contents,stopwords): # 输入参数为每个用户评价的分词列表,以及停用词
segments_clean = [] # 设置一个空列表,用于存放处理完的每个用户的评价词组列表
for content in contents: # 遍历列表中的每个用户的评价内容
line_clean = [] # 定义一个空列表用于存放每个用户排除停用词后的词组
for word in content: # 遍历每个用户评价的分词单词
if word in stopwords: # 如果分的词在停用词中,那么跳过当前循环,继续下一次循环
continue
line_clean.append(word) # 如果不在停用词里那么将这个词写入列表
segments_clean.append(line_clean) # 每处理完一个用户的评论,就将这个用户词组的列表存放到这个列表内
return segments_clean # 返回值为处理完的所有用户的词组列表
# 调用去除停用词函数
contents = cp_fc_results.content.values.tolist() # cp_fc_results为上述生成的差评词组的DF类型数据,取出每个用户的分词结果,并将其转变成列表形式
stopwords = stopwords.stopword.values.tolist() # 取出停用词的每一条数据,并将其转变成列表形式
cp_fc_contents_clean_s = drop_stopwords(contents,stopwords) # 调用上述排除停用词函数,排除所有的停用词
contents = yzpj_fc_results.content.values.tolist() # 这里同样对好评的数据转变成列表数据
yzpj_fc_contents_clean_s = drop_stopwords(contents,stopwords) # 调用函数去除停用词
print(yzpj_fc_contents_clean_s)
2)得到除去了停用词的词组
三、词向量转化
1、建立训练集、测试集数据
import pandas as pd
cp_train= pd.DataFrame({'segments_clean':cp_fc_contents_clean_s, 'label':1}) # 将上述生成的差评词组列表转换成DF类型,并设置一个类别列,里面的值全为1
yzpj_train= pd.DataFrame({'segments_clean':yzpj_fc_contents_clean_s, 'label':0}) # 将好评的分词列表转换成DF类型后设置类别为0
pj_train = pd.concat([cp_train,yzpj_train]) # 合并两个二维数据
pj_train.to_excel('pj_train.xlsx',index=False) # 将包含所有用户的词组及评级类别保存成excel类型文件
from sklearn.model_selection import train_test_split # 导入切分库
x_train,x_test,y_train,y_test = train_test_split(pj_train['segments_clean'].values,pj_train['label'].values, random_state=0) # 将总体数据随机切分为训练集和测试集数据
words =[] # 定义个空列表,用于存放每个用户的评价内容,为了转换为词向量CountVectorizer所能识别的列表类型
for line_index in range(len(x_train)): # 遍历训练集的每一条特征数据,即每个用户的评价词组,以空格为分隔符,将每个用户的所有词组转变为字符串形式存入列表word
words.append(' '.join(x_train[line_index]))
print(words)
运行结果为:
2、导入词向量转换库
1)什么是词向量转换库?
词向量转换库是一种用于将文本数据中的词语转换为对应的数值向量表示的工具库。它将每个词语映射到一个高维空间中的向量,以捕捉词语之间的语义和上下文关系。
2)导入
# 导入词向量转化库
from sklearn.feature_extraction.text import CountVectorizer
# 建立模型,lowercase参数的功能:把所有的词是是否需要转换为小写。False。
# max_features:表示只提取前4000个词作为词库
vec = CountVectorizer(max_features=4000,lowercase = False, ngram_range=(1,1))
vec.fit(words) # 传入训练集的所有文字,根据文字构建模型,要将训练集 的所有单词作为词库,一会还有测试集的文本,
四、导入贝叶斯分类器
1、导入分类器模型
from sklearn.naive_bayes import MultinomialNB,ComplementNB
MultinomialNB:多项式朴素贝叶斯分类器。适用于离散特征(例如,文本中单词出现的次数)的分类问题。它使用多项式分布来建模特征的概率分布。
ComplementNB:补充朴素贝叶斯分类器。它是对多项式朴素贝叶斯分类器的一种改进,尤其适用于不平衡的数据集。它使用补充概率进行模型训练。
2、代码如下
# 导入朴素贝叶斯分类器"
from sklearn.naive_bayes import MultinomialNB,ComplementNB # 导入分类器模型
classifier = MultinomialNB(alpha = 0.1) # 建立贝叶斯模型,并设置平滑系数为0.1
classifier.fit(vec.transform(words),y_train) # 将上述通过词向量转化产生的文本数据转变成特征向量,然后对其进行训练
train_pr = classifier.predict(vec.transform(words)) # 对特征向量的训练集自己进行预测
#训练集数据预测得分
from sklearn import metrics
print(metrics.classification_report(y_train, train_pr)) # 打印训练集的分类结果,参数为标签类别及预测结果
#测试集数据进行分析
test_words =[] # 设置一个空列表用于存放每个用户评价的词组列表数据
for line_index in range(len(x_test)): # 将每个用户的评价分词词组列表转变成一个字符串类型,然后再存入列表
test_words.append(' '.join(x_test[line_index]))
test_pr = classifier.predict(vec.transform(test_words)) # 测试集数据预测得分
print(metrics.classification_report(y_test, test_pr)) # 分类结果
运行结果为:
3、输入数据进行测试
s = '这个玩意真好,我很喜欢' # 设置一条评论,用于判断是好评还是差评
a = []
a0 = jieba.lcut(s) # 将字符串评价进行切分
for i in a0: # 遍历分词后的每一个单个词组
if len(a0) > 1: # 判断如果词组长度大于1那么将其存入列表a
a.append(a0)
a1 = pd.DataFrame({'content':a},) # 将列表a转变为DF类型,并设置列名为content
a2 = a1.content.values.tolist() # 对DF类型的a1,取出content列的所有的值,将其转变为列表类型
a1_clean_s=drop_stopwords(a1,stopwords) # 调用上述的去停用词函数,得到干净词组数据
word_1 = [] # 定义个空列表
for line_index in range(len(a1_clean_s)): # 遍历上述干净词组列表的每一个数据,将其以分隔符为空格的形式取出并拼接为字符串类型
word_1.append(' '.join(a1_clean_s[line_index]))
predict_word_1 = classifier.predict(vec.transform(word_1)) # 将字符串转变为稀疏矩阵后对其进行测试,然后输出预测类型,上述设置的0为优质评价,1为差评
print(predict_word_1)
运行结果为:
预测成功!