python爬取网页新闻内容_python实现爬取网页新闻并进行文本分类(用K-Means算法实现)...

这篇博客介绍了如何使用Python爬取观察者网的新闻内容,并利用jieba分词、K-Means算法进行文本分类。首先,文章详细阐述了爬虫的实现过程,包括设置请求头、解析HTML和保存文本。接着,通过停用词表和TF-IDF计算对文本预处理,然后应用K-Means进行聚类。尽管作者认为K-Means在文本分类效果一般,但依然推荐了这个方法。
摘要由CSDN通过智能技术生成

编译器:Anaconda3里的spyder(python3.7)编译器

事先要确定编译器里有这几个库:urllib,bs4,jieba,os,math,heapq,Bio,numpy

这个程序是以爬取观察者网上的部分新闻为例。

jieba库的基本用法: https://github.com/fxsjy/jieba

停用词表:https://blog.csdn.net/shijiebei2009/article/details/39696571

TD-IDF值计算的参考文档:https://blog.csdn.net/sangyongjia/article/details/52440063

使用Bio库里的kcluster函数进行K-Means算法的基础讲解:https://biopython-cn.readthedocs.io/zh_CN/latest/cn/chr15.html#uncentered-correlation

代码里的文件文件路径是我自己电脑上的路径,大家在复制代码去自己计算机上测试的时候别忘了改文件路径。

之前是选用的另一个库里的一个K-Means算法函数,但是那个函数默认是使用欧氏距离来计算点之间的距离,并且没法修改,而这个函数有多种计算距离的公式可供使用,更加的灵活,强烈推荐使用。

基本每一行代码我都有写注释,这里就不对代码本身做过多的讲解了(其实是因为我懒),大家自己看吧~

其实我感觉用K-Means算法来对文本进行分类的效果不是很好,因为无法计算分类的准确率啦,也不知道该分成多少类好啊,如果有时间的话,我之后再用朴素贝叶斯算法再做一遍。

有问题欢迎讨论(时间短的话我可能还能回答,过一段时间可能我自己都忘了是怎么做的了)

下面是代码,复制到自己的编译器上即可使用。

import urllib.request as eq

from bs4 import BeautifulSoup

import  jieba

import os

import math

import heapq

from Bio.Cluster import kcluster

import numpy

#爬虫程序段

def pachong():#爬虫程序段

biaoqian=[]

list1=[]#设置一个列表来存放链接

url='https://www.guancha.cn//'#抓取的网址

p=1

req=eq.Request(url=url)#创建Request对象

#设置访问网页时的信息头,将自己伪装成一个正常的浏览器访问

req.add_header("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4098.3 Safari/537.36")

data = eq.urlopen(url).read()#将网页源代码放在变量data中

soup = BeautifulSoup(data, "lxml")#将data变量中的网页源代码整理了一下储存在soup变量中

#tmp1=soup.find_all('h4',class_='module-title')#将所有‘h4’中class='module-title'的标签取出来

tmp=soup.find_all('div',class_='resemble-art c_hidden')#将所有‘div’中class='resemble-art c_hidden'的标签取出来

for i in tmp:#将所有该标签下的链接取出来

start=str(i).find('a href="')#返回这段文字匹配到的第一个字符的位置

end=str(i).find('" target="_blank"')#返回这段文字的第一个字符位置

a=str(i)[start+8:end]#取字符串的一部分

biaoqian.append(a)

list1.append('https://www.guancha.cn'+a)

for j in list1:

rurl=j

req=eq.Request(url=rurl)#创建Request对象

#设置访问网页时的信息头,将自己伪装成一个正常的浏览器访问

req.add_header("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4098.3 Safari/537.36")

data = eq.urlopen(rurl).read()#将网页源代码放在变量data中

soup = BeautifulSoup(data, "lxml")#将data变量中的网页源代码整理了一下储存在soup变量中

a=soup('p')

dizhi="D:/学习/数据挖掘与机器学习/爬虫下载文件位置/观察者网"+str(p)+".txt"

wenjian=open(dizhi, "w+",encoding='utf-8')#打开一个可读写文件

k=0

while k

wenjian.write("".join(a[k].text.split()))#把文本写入文件中,"".join(a[k].text.split()):去除文本中的空格和换行符

k=k+1

wenjian.close()

p+=1

return biaoqian;

#加载停用词

def tinyongci():

tyc=[]

tyc_wj=open("D:/学习/数据挖掘与机器学习/停用词.txt", "r",encoding='utf-8').read()#该行代码在使用时应把停用词的路径修改为自己电脑上的路径

str1=''

for i in tyc_wj:#遍历文档里的字符

if i in '\n':#换行符在txt文本中被当做间隔符,遇到换行符说明str1中存放的是一个完整的停用词了

tyc.append(str1)#将str1中的停用词添加到tyc列表中

str1=''#重置str1

else:

str1=str1+i#如果不是换行符就说明该字符是停用词的一部分,将其添加进str1中

tyc.append(str1)#将最后一个停用词添加进tyc列表中

return tyc

#结巴分词

def jiebafenci():

list1=[]

list_name=[]

txt=''

counts = {}     # 通过键值对的形式存储词语及其出现的次数

for i in os.listdir("D:/学习/数据挖掘与机器学习/爬虫下载文件位置"):

list_name.append(i)#读取该文件夹内的所有文件名字

for i in list_name:

dizhi="D:/学习/数据挖掘与机器学习/爬虫下载文件位置/"+str(i)

wenjian=open(dizhi, "r",encoding='utf-8')#用只读的模式打开文件

txt=txt+wenjian.read()

words = jieba.lcut(txt)#使用精确模式对文本进行分词

for word in words:#去除列表中的停用词

if len(word) == 1:    # 单个词语不计算在内

continue

elif (tyc.count(word) == 1):#停用词不计算在内

continue

else:

counts[word] = counts.get(word, 0) + 1  # 遍历所有词语,每出现一次其对应的值加 1

items = list(counts.items())#返回一个元组类型的字典键值对,再转化为列表

items.sort(key=lambda x: x[1], reverse=True)    # 根据词语出现的次数进行从大到小排序

for i in range(len(items)):

list1.append(items[i][0])

return list1

#IF_IDF矩阵

def IF_IDF():

list2=[]

list3=[]

list_name=[]

for i in os.listdir("D:/学习/数据挖掘与机器学习/爬虫下载文件位置"):

list_name.append(i)#读取该文件夹内的所有文件名字

for i in list_name:

dizhi="D:/学习/数据挖掘与机器学习/爬虫下载文件位置/"+str(i)

wenjian=open(dizhi, "r",encoding='utf-8')#用只读的模式打开文件

words = jieba.lcut(wenjian.read())#使用精确模式对文本进行分词

counts={}

counts=counts.fromkeys(list1, 0)#建立一个用来计算词语出现次数的字典

for word in words:

if word in counts:

counts[word]+=1# 遍历所有词语,每出现一次其对应的值加 1

list3=[]

for j in counts:

list3.append(counts[j])#将字典中的值赋值给列表

list2.append(list3)#做一个嵌套列表用来存放每篇文章中词语出现次数

return list2

#求每篇文章中词频最高的词

def ci_benwen():

list3=[]

for i in range(len(list2)):

list3.append(list1[list2[i].index(max(list2[i]))])

return list3

#找出所有文章中TF-IDF值前五大的词

def ci_quanbu():

tf=[]

idf=[]

tf_idf=[]

d=len(list2)

list5=[]

list9=[]

for i in range(len(list2)):#用来算出tf(频率)的值

list4=[]

for j in range(len(list2[i])):

list4.append(list2[i][j]/(sum(list2[i])+1))#计算频率的公式

tf.append(list4)

for i in range(len(list2[0])):#算idf的值

list5.append(0)

for j in range(len(list2)):

if list2[j][i]>0:

list5[i]+=1#求某个词在几篇文章中出现过

idf.append(math.log(d/list5[i]))#算idf的公式

for i in range(len(list2)):#计算tf-idf的值

list6=[]

for j in range(len(list2[i])):

list6.append(idf[j]*tf[i][j])#两两相乘得出tf-idf的值

tf_idf.append(list6)

list7=list(numpy.max(tf_idf,axis=0))#取出每个词的最大tf-idf值

list8=heapq.nlargest(5, list7)#找出tf-idf最大的五个数值

for i in list8:

list9.append(list1[list7.index(i)])#将数值对应的词存入list9列表中

return tf_idf,list9

def k_means():

print('\nStart Kmeans:')

'''这个函数的返回值为一个包含 (clusterid, error, nfound) 的元组,

其中 clusterid 是 一个整型矩阵,为每行或列所在的类。

error 是最优聚类解中,每类内距离的总和, nfound 指的是最优解出现的次数。'''

clusterid, error, nfound = kcluster(tf_idf,dist='u')#Bio库中使用kmeans算法的结果;u表示使用余弦相似度算法

#每个样本所属的簇

print(clusterid)

i = 1

while i <= len(clusterid):

print(i, clusterid[i-1])

i = i + 1

return clusterid, error, nfound

if __name__ == '__main__':

tyc=tinyongci()#加载常用的停用词

biaoqian=pachong()#爬虫程序段

list1=jiebafenci()#list1存放的是整篇文章中73个高频率词

list2=IF_IDF()#list2是tf-idf矩阵

list3=ci_benwen()#list3存放的是每篇文章中的最高频的词

print('每篇文章中的最高频的词:')

for i in range(len(list3)):

print(i+1,list3[i])

tf_idf,list9=ci_quanbu()#tf_idf存放的是每个词的tf_idf数值;list9存放的是tf_idf最大的五个词

print('\ntf_idf最大的五个词:')

for i in range(5):

print(i+1,list9[i])

clusterid, error, nfound = k_means()#使用kmeans算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值