python爬蟲爬取網易新聞,并對新聞文本進行分類

文章目錄

一、爬蟲部分

1、目標網站:網易新聞

首先我們看到最上方綠色方框圈中的部分,這就是我們要爬取的分類。在這里我一共選擇了國內、國際、軍事、航空、科技這五個分類進行爬取
接下來我們以打開國內的新聞為例進行分析

2、分析網址

我們打開開發(fā)者工具,來尋找我們的數據
選擇network,刷新網頁,找js,找到后臺json數據(如下圖所示)


在這里插入圖片描述

那么接下來我們查看它的headers獲取它的鏈接地址就可以開始構造代碼了。

3、構造URL

我們可以看到headers中的請求地址,不同類別新聞的請求地址的不同之處在于紅框中的 部分


在這里插入圖片描述

代碼如下,每個類別的請求地址為兩個(第一個為第一頁地址,第二個為后面若干頁地址)

#要爬取的新聞分類地址國內、國際、軍事、航空、科技
url_list={'國內':[ 'https://temp.163.com/special/00804KVA/cm_guonei.js?callback=data_callback',
                   'https://temp.163.com/special/00804KVA/cm_guonei_0{}.js?callback=data_callback'],
         '國際':['https://temp.163.com/special/00804KVA/cm_guoji.js?callback=data_callback',
                 'https://temp.163.com/special/00804KVA/cm_guoji_0{}.js?callback=data_callback'],
         '軍事':['https://temp.163.com/special/00804KVA/cm_war.js?callback=data_callback',
               'https://temp.163.com/special/00804KVA/cm_war_0{}.js?callback=data_callback'],
         '航空':['https://temp.163.com/special/00804KVA/cm_hangkong.js?callback=data_callback&a=2',
               'https://temp.163.com/special/00804KVA/cm_hangkong_0{}.js?callback=data_callback&a=2'],
         '科技':['https://tech.163.com/special/00097UHL/tech_datalist.js?callback=data_callback',
              'https://tech.163.com/special/00097UHL/tech_datalist_0{}.js?callback=data_callback']}

4、解析頁面

針對每一頁的內容,獲取到json數據后提取新聞標題

titles=[]
categories=[]
def get_result(url):
    global titles,categories
    temp=parse_class(url)
    #去除空白頁
    if temp[0]=='>網易-404</title>':
        return False
    print(url)
    titles.extend(temp)
    temp_class=[key for i in range(len(temp))]
    categories.extend(temp_class)
    return True

循環(huán)爬取所有頁面

for key in url_list.keys():
    #按分類分別爬取
    print("=========正在爬取{}新聞===========".format(key))
    #遍歷每個分類中的子鏈接
    #首先獲取首頁
    get_result(url_list[key][0])
    #循環(huán)獲取加載更多得到的頁面
    for i in range(1,10):
        try:
            if get_result(url_list[key][1].format(i)):
                pass
            else:
                continue
        except:
            break
print("爬取完畢!")

5、保存數據

由于新聞具有實時性,每天,或者每天的不同時間段會有不同的新聞產生,因此在保存前將此次爬取中與之前保存的數據中重復內容刪除再保存,以達到擴充數據集的目的。

def update(old,new):
    '''
    更新數據集:將本次新爬取的數據加入到數據集中(去除掉了重復元素)
    '''
    data=new.append(old)
    data=data.drop_duplicates()
    return data
    
new=pd.DataFrame({
    "新聞內容":titles,
    "新聞類別":categories
})
old=pd.read_csv("新聞數據集.csv",encoding='gbk',engine='python')
print("更新數據集...")
df=update(old,new)
df.to_csv("新聞數據集.csv",index=None,encoding='gbk')
print("更新完畢,共有數據:",df.shape[0],"條")

這樣所有的內容就爬取下來了。
可視化看下爬到的各個分類的新聞的數量

在這里插入圖片描述

接下來我們就要對爬取到的內容進行文本分類.

二、文本分類

1、數據清洗、分詞

首先需要清理掉停用詞,以及標點符號。停用詞可以直接百度搜索停用詞表非常多,將爬取的文本數據中的停用詞去掉即可。

def remove_punctuation(line):
    line = str(line)
    if line.strip()=='':
        return ''
    rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]")
    line = rule.sub('',line)
    return line
 
def stopwordslist(filepath):  
    stopwords = [line.strip() for line in open(filepath, 'r', encoding="UTF-8").readlines()]  
    return stopwords  
 
#加載停用詞
stopwords = stopwordslist("./stop_words.txt")
#刪除除字母,數字,漢字以外的所有符號
df['clean_review'] = df['新聞內容'].apply(remove_punctuation)
#分詞,并過濾停用詞

df['cut_review'] = df['clean_review'].apply(lambda x: " ".join([w for w in list(jb.cut(x)) if w not in stopwords]))
print("數據預處理完畢!")

2、tf-idf詞向量,構建樸素貝葉斯模型

數據清洗完畢后直接使用sklearn提供的庫將文本數據轉換成詞向量,進行數據集切分,開始訓練

#轉詞向量
tfidf = TfidfVectorizer(norm='l2', ngram_range=(1, 2))
features = tfidf.fit_transform(df.cut_review)
labels = df.新聞類別
#劃分訓練集
x_train,x_test,y_train,y_test=train_test_split(features,labels,test_size=0.2,random_state=0)
model=MultinomialNB().fit(x_train,y_train)
y_pred=model.predict(x_test)
print("模型訓練完畢!")

3、模型評估

這里我們使用混淆矩陣來對模型進行評估

# 繪制混淆矩陣函數
def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    plt.figure(figsize=(8,6))
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('真實標簽')
    plt.xlabel('預測標簽')
    plt.show()
class_names=['軍事','國內','國際','科技','航空']
cm= confusion_matrix(y_test, y_pred)
title="分類準確率:{:.2f}%".format(accuracy_score(y_test,y_pred)*100)
plot_confusion_matrix(cm,classes=class_names,title=title)
print("分類評估報告如下:\n")
print(classification_report(y_test,y_pred))
在這里插入圖片描述

到此我們整個爬蟲+數據分析建模的過程就結束了,要是對準確率有要求可以去嘗試更多不同模型。


完整代碼和數據集以及停用詞表可關注以下公眾號回復"0002"獲取


在這里插入圖片描述
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容