import requests
from bs4 import BeautifulSoup
import jieba
import os
import re
"""让jieba库不显示红字,并且调用自定义分词词典"""
jieba.setLogLevel(20)
jieba.load_userdict("dict.txt")
"""在该处字典内输入板块的网页编号id,即可提取相应页面的标题"""
nga_dict = {
'网事杂谈':'-7',
'守望先锋':'459',
'守望先锋联赛': '587',
'炉石传说':'422',
'晴风村':'-7955747',
'PC软硬件': '334',
'酒馆战棋': '690',
'大时代': '706',
'二次元国家地理': '-447601',
'Nintendo游戏综合讨论': '616'
}
name = input("请输入板块名称:").strip() #获取板块名称,即使输入者输入了空格也无所谓
number = int(input("请输入想统计该板块前多少页的数据:").strip()) #获取想要获取页的数据,即使输入者输入了空格也无所谓
"""如果文件夹内已存在该板块标题统计过的数据,则删除该文件,以保留最新数据"""
path = '{}.txt'.format(name)
if os.path.exists(path):
os.remove(path)
"""爬取网页标题,分行保存到本地txt文件"""
for page in range(number): #提取前10页的标题,此处用for构建10次
page = page + 1 #range函数从0开始,我们需求从1页开始,所以+1即可
url = 'https://bbs.nga.cn/thread.php?fid={}&page={}'.format(nga_dict[name],page) #构建url,nga的url很规律,就是page=某个数字就代表第几页
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
} #构建浏览器的请求头,不管网站是否需要,构建了总没坏处
cookie = "UM_distinctid=17a24dcfed59bb-0089785281b34f-4373266-1fa400-17a24dcfed67ca; ngacn0comUserInfo=%25BA%25DA%25D1%25A9%25BC%25A7hime%09%25E9%25BB%2591%25E9%259B%25AA%25E5%25A7%25AChime%0939%0939%09%0910%0915100%094%090%090%0971_90; ngaPassportUid=39747826; ngaPassportUrlencodedUname=%25BA%25DA%25D1%25A9%25BC%25A7hime; ngaPassportCid=X8q4lggaik2uf49e0g14bpq31ou34r10rs0f95np; ngacn0comUserInfoCheck=02470d6d421c80354243575c27024ae3; ngacn0comInfoCheckTime=1631242975; CNZZDATA30043604=cnzz_eid%3D1572936604-1592654904-%26ntime%3D1631249229; lastvisit=1631254001; lastpath=/thread.php?fid=-7; bbsmisccookies=%7B%22pv_count_for_insad%22%3A%7B0%3A-16%2C1%3A1631293263%7D%2C%22insad_views%22%3A%7B0%3A1%2C1%3A1631293263%7D%2C%22uisetting%22%3A%7B0%3A%22a%22%2C1%3A1631253707%7D%7D; _cnzz_CV30043604=forum%7Cfid-7%7C0"
#从网页源码内原封不动贴来的cookie
cookie_dict = {i.split("=")[0]:i.split("=")[-1] for i in cookie.split("; ")}
#把cookie转换为字典形式
r = requests.get(url, headers=headers,cookies = cookie_dict) #获取网页源码
soup = BeautifulSoup(r.text, 'lxml') #用bs4的lxml库解析源码
print(soup)
for each in soup.find_all('tbody'): #查看源码,可以知道我们要的标题都在tbody标签下,用for循环,find_all函数去找到所有的tbody标签
title = each.find('a',class_ = 'topic').get_text(strip=True) #查看源码,可以知道我们要的标题都是tbody标签下的a子标签,class为topic
#的标签,即为想要的标题,用get_text函数获取文本,strip去除没有必要的空格
file = open('{}.txt'.format(name),'a',encoding='utf-8') #打开topic.txt,没有则创建一个
file.write('\n'.join([title])) #将刚刚获取的标题写入txt,并换行
file.write('\n')
file.close()
"""分行读取txt文件内的文本,运用正则匹配消除板块内固定[xxx]样式的子标题内容,防止干扰分词库统计无意义的内容"""
word = open('{}.txt'.format(name),'r',encoding='utf-8').readlines() #打开name.txt,此时里面已有相应版块指定页数的标题
word_strip = [] #生成空列表,用于保存消除可能作为干扰项的[xx]样式前缀标题
for x in word: #运用for循环,遍历txt文件内每行,即每个标题的内容
x = re.sub(r'\[\S*]', '',x) #运用正则,筛选出[xx]样式,sub函数替换成空值,\S代表非空格的任意字符,*代表前方匹配多次,如没有则不匹配
x = x.replace("\n", "").strip() #因为readlines读出来的数据会有换行符,此处我们也替换成空值,如果首尾有空格,消除
word_strip.append(x) #将值添加到word_strip列表中
word_last = [] #生成空列表,用于保存最终分词后得到的词语
for word_new in word_strip: #运用for循环,遍历word_strip列表,即已经经过清洗后的每个标题内容
for x in jieba.lcut(word_new):
if len(x) >= 2:
word_last.append(x) #将每个句子分成词,如果该词长度大于等于二,即非单字,则添加到列表中
from collections import Counter #import counter库,用于计数筛选词频
result = Counter(word_last) #计数
dict_result = dict(result) #将计数转换成字典,用于去除干扰词
"""设置自定义无用项列表,列举常用语气助词,辅助用语等无需统计的数据"""
gr_word = open('干扰词.txt','r',encoding='utf-8').readlines() #读取干扰词文本
remove_word = [] #生成干扰词文本空列表,用于存储干扰词
for w in gr_word: #用for循环,replace函数去除所有的换行符,添加到干扰词列表内
w = w.replace("\n", "")
remove_word.append(w)
for a in remove_word: #遍历干扰词列表
if a in dict_result: #如果计数得到的字典内存在干扰词,去除干扰词
dict_result.pop(a)
print(Counter(dict_result)) #再次计数,此时得到的即为最终结果,也可以接着用mataplotlib库画图
运用爬虫和分词库统计nga某板块标题词频
最新推荐文章于 2023-06-15 17:09:27 发布