python金融大數(shù)據(jù)挖掘與分析——新聞數(shù)據(jù)挖掘

@[toc]

1. 提取百度新聞標(biāo)題、網(wǎng)址、日期及來源

1.1 獲取網(wǎng)頁源代碼

我們通過如下代碼可以獲取網(wǎng)頁源代碼,示例中代碼是獲取在百度新聞中搜索阿里巴巴的網(wǎng)頁源代碼。

import requests

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                             'AppleWebKit/537.36 (KHTML, like Gecko) '
                             'Chrome/77.0.3865.120 Safari/537.36'}
res = requests.get(url, headers=headers)
web_text = res.text

因?yàn)榘俣刃侣劸W(wǎng)站只認(rèn)可瀏覽器發(fā)送的請求,所以需要設(shè)置headers參數(shù),以模擬瀏覽器的發(fā)送請求,chrome瀏覽器可以通過about:version獲取。

1.2 編寫正則表達(dá)式提取新聞信息

1.2.1 提取新聞的來源和日期

在這里插入圖片描述

通過觀察網(wǎng)頁源碼,我們發(fā)現(xiàn)每條新聞的來源和發(fā)布日期都夾在<p class="c-author">和</p>之間,因此,可以通過正則表達(dá)式獲取中間的來源和日期信息。

pattern = '<p class="c-author">(.*?)</p>'
info = re.findall(pattern, web_text, re.S)      # re.S用于考慮換行符,因?yàn)?和*不包含換行符
print(info)

獲取的信息中包含了很多諸如空格、換行符、制表符以及<img>標(biāo)簽的內(nèi)容,需要對數(shù)據(jù)進(jìn)行二次清洗,這部分內(nèi)容將在后面章節(jié)介紹到。

1.2.2 提取新聞的網(wǎng)址和標(biāo)題。

為了提取新聞網(wǎng)址和標(biāo)題,需要像上節(jié)那樣從網(wǎng)頁源碼中發(fā)現(xiàn)規(guī)律,通過獲取的源碼,我們發(fā)現(xiàn),新聞地址前面都有<h3 class="c-title">。


在這里插入圖片描述

通過如下兩段代碼,可以分別獲取新聞的網(wǎng)址和標(biāo)題。

    pattern_herf = '<h3 class="c-title">.*?<a href="(.*?)"'
    herf = re.findall(pattern_herf, web_text, re.S)
    print(herf)

    pattern_title = '<h3 class="c-title">.*?>(.*?)</a>'
    title = re.findall(pattern_title, web_text, re.S)
    print(title)

獲取的數(shù)據(jù)同樣需要進(jìn)行二次數(shù)據(jù)清洗。

1.2.3 數(shù)據(jù)清洗

  1. 新聞標(biāo)題清洗
    提取的新聞標(biāo)題數(shù)據(jù)存在兩個問題:一是每個標(biāo)題的收尾含有換行符和一些空格;二是中間含有<em>和</em>等無效字符。

(1)通過stip()函數(shù)把不需要的空格和換行符去掉。

for i in range(len(title)):
    title[i] = title[i].strip()

(2)用sub()函數(shù)處理<em>和</em>

for i in range(len(title)):
    title[i] = title[i].strip()
    title[i] = re.sub('<.*?>', '', title[i])
  1. 新聞來源和日期清理
    提取的新聞來源和日期中存在的問題:夾雜著很多<imag>標(biāo)簽信息;新聞來源和日期連在一起;夾雜著很多換行符、制表符、空格符等
    for i in range(len(info)):
        info[i] = re.sub('<.*?>', '', info[i])            # 清洗<img>標(biāo)簽信息
        source.append(info[i].split('&nbsp;&nbsp;')[0])   # 將新聞來源和日期分開
        date.append(info[i].split('&nbsp;&nbsp;')[1])
        source[i] = source[i].strip()
        date[i] = date[i].strip()

2. 批量獲取多家公司的百度新聞并生成數(shù)據(jù)報告

本章主要實(shí)現(xiàn)批量獲取多家公司的信息,并自動生成數(shù)據(jù)報告,導(dǎo)出為一個文本文件

2.1 批量爬取多家公司的百度新聞

這里,我們將爬取網(wǎng)頁的工作封裝成一個函數(shù)。

def baidu_news(company):
    """
    獲取網(wǎng)頁源碼,并提取百度新聞標(biāo)題、網(wǎng)址、日期和來源
    :param company: 公司名稱
    :return: 網(wǎng)頁源碼
    """
    url = 'https://www.baidu.com/s?rtt=1&bsst=1&cl=2&tn=news&word=' + company
    # 百度新聞網(wǎng)站只認(rèn)可瀏覽器發(fā)送的請求,所以需要設(shè)置headers參數(shù),
    # 以模擬瀏覽器的發(fā)送請求,chrome瀏覽器可以通過about:version獲取
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                             'AppleWebKit/537.36 (KHTML, like Gecko) '
                             'Chrome/77.0.3865.120 Safari/537.36'}
    res = requests.get(url, headers=headers)
    web_text = res.text

    # 獲取新聞的來源和日期
    pattern = '<p class="c-author">(.*?)</p>'
    info = re.findall(pattern, web_text, re.S)  # re.S用于考慮換行符,因?yàn)?和*不包含換行符
    # print(info)

    # 獲取新聞的網(wǎng)址和標(biāo)題
    pattern_herf = '<h3 class="c-title">.*?<a href="(.*?)"'
    herf = re.findall(pattern_herf, web_text, re.S)
    # print(herf)

    pattern_title = '<h3 class="c-title">.*?>(.*?)</a>'
    title = re.findall(pattern_title, web_text, re.S)
    # print(title)

    # title 數(shù)據(jù)清洗
    for i in range(len(title)):
        title[i] = title[i].strip()
        title[i] = re.sub('<.*?>', '', title[i])

    # print(title)

    # 新聞來源和日期清洗
    source = []
    date = []

    for i in range(len(info)):
        info[i] = re.sub('<.*?>', '', info[i])  # 清洗<img>標(biāo)簽信息
        source.append(info[i].split('&nbsp;&nbsp;')[0])  # 將新聞來源和日期分開
        date.append(info[i].split('&nbsp;&nbsp;')[1])
        source[i] = source[i].strip()
        date[i] = date[i].strip()

        print(str(i+1) + '.' + title[i] + '(' + date[i] + '-' + source[i] + ')')

然后再主函數(shù)中編寫調(diào)用過程。

    companys = ['華能信托', '騰訊', '阿里巴巴']
    for company in companys:
        baidu_news(company)
        print(company + '百度新聞爬取成功')

結(jié)果如下所示:

1.信托業(yè)績哪家強(qiáng)?兩家去年凈利超30億 華宸華融有點(diǎn)“慘淡”(2020年01月21日 23:38-每日經(jīng)濟(jì)新聞)
2.57家信托業(yè)績哪家強(qiáng)?中信、華能、重慶信托穩(wěn)坐前三(2020年01月20日 07:47-新浪財經(jīng))
3.2019年凈利潤排位確定:中信信托35.93億獨(dú)占鰲頭(2020年01月16日 16:51-金融界)
4.關(guān)于為“華能信托-鏈融科技誠意2期供應(yīng)鏈金融資產(chǎn)支持專項(xiàng)計劃”...(2020年01月16日 23:10-金融界)
5.2019信托公司業(yè)績哪家強(qiáng)?(2020年01月17日 19:53-中國金融新聞網(wǎng))
6.去年信托調(diào)研185家上市公司 電子設(shè)備制造業(yè)成為重點(diǎn)(2020年01月06日 10:07-中國基金會網(wǎng))
7.關(guān)于為“華能信托-一方誠意3期供應(yīng)鏈金融資產(chǎn)支持專項(xiàng)計劃”提供...(2020年01月06日 23:10-新浪)
8.牧原股份聯(lián)合華能信托 擬72億元設(shè)立兩家養(yǎng)豬子公司(2019年12月11日 22:28-同花順財經(jīng))
9.牧原股份生豬養(yǎng)殖多地開花 借力華能信托找錢(2019年12月11日 10:32-財新)
10.牧原股份(002714.SZ)與華能貴誠信托設(shè)立的合資公司已注冊成立(2019年12月12日 21:09-新浪)
華能信托百度新聞爬取成功
1.廣東首例N95口罩詐騙案告破 騰訊協(xié)助警方破案(1小時前-中國新聞網(wǎng))
2.抗擊疫情 騰訊聯(lián)合微醫(yī)等五平臺提供義診服務(wù)(1小時前-新浪)
3.騰訊聯(lián)合五大平臺,在線義診新型肺炎(1小時前-手機(jī)鳳凰網(wǎng))
4.騰訊文檔開放免費(fèi)會員,全面支持遠(yuǎn)程辦公(4小時前-新浪)
5.最慘游戲工作室!13年9款神作卻窮得叮當(dāng)響,騰訊看中后出手了(1小時前-17173游戲網(wǎng))
6.音樂戰(zhàn)“疫”進(jìn)行時 TME騰訊音樂人踴躍創(chuàng)作公益歌曲“聲”援武漢(54分鐘前-騰訊科技)
7.如果說國行NS不是騰訊和任天堂合作的重點(diǎn),那什么是重點(diǎn)?(1小時前-新浪)
8.騰訊云向黃牛教授實(shí)驗(yàn)室,羅海彬教授團(tuán)隊提供免費(fèi)云超算等(23分鐘前-鈦媒體)
9.停課不停學(xué) 騰訊課堂助力重慶十一中高三線下課首次線上開課(6小時前-環(huán)球網(wǎng))
10.騰訊文檔開放免費(fèi)會員功能 協(xié)同編輯人數(shù)至200人(50分鐘前-中關(guān)村在線)
騰訊百度新聞爬取成功
1.阿里巴巴全球14國直采醫(yī)療物資馳援,將通過東方航空陸續(xù)抵漢(39分鐘前-武漢發(fā)布)
2.阿里巴巴全球采購醫(yī)療物資 首批N95口罩今日運(yùn)抵武漢(29分鐘前-浙江新聞)
3.阿里巴巴與東航合力 在14國采購與運(yùn)輸醫(yī)療物資(1小時前-新浪)
4.阿里巴巴全球采購醫(yī)療物資陸續(xù)抵滬(48分鐘前-同花順財經(jīng))
5.阿里巴巴一紙“禁令”后,商家祭出高仿口罩!抓住這點(diǎn)、一招鑒別(9分鐘前-IT爆料王)
6.阿里巴巴等百家企業(yè)承諾:防疫、民生用品價格不漲(6小時前-TechWeb)
7.【阿里巴巴等多個企業(yè)共同發(fā)出“三保行動 讓我們一起出發(fā)”的倡議】(5小時前-新浪)
8.阿里巴巴上線發(fā)熱門診查詢 已覆蓋5734個發(fā)熱門診(2020年01月29日 11:10-中國新聞網(wǎng))
9.武漢疫情口罩脫銷,阿里巴巴發(fā)出緊急通知,這種口罩不能買!(1小時前-科技季節(jié))
10.阿里巴巴等多家企業(yè)響應(yīng)市場監(jiān)管總局“三?!毙袆?2020年01月29日 23:47-新浪財經(jīng))
阿里巴巴百度新聞爬取成功

2.2 自動生成輿情數(shù)據(jù)報告文本文件

上一節(jié)已經(jīng)爬取到了我們想要的新聞,并生成了輿情結(jié)果,下面將其導(dǎo)出到文本文件中。
在baidu_news()函數(shù)后面增加導(dǎo)出到文件的相關(guān)操作代碼如下:

    file_ = open('數(shù)據(jù)挖掘報告.txt', 'a')     #追加模式,不清除原來的數(shù)據(jù)
    file_.write(company + '新聞數(shù)據(jù):' + '\n' + '\n')
    for i in range(len(title)):
        file_.write(str(i+1) + '.' + title[i] + '(' + date[i] + '-' + source[i] + ')' + '\n')
        file_.write(href[i] + '\n')

    file_.write('————————————————————————————————————————————' + '\n' + '\n')
    file_.close()

3. 異常處理及24小時實(shí)時數(shù)據(jù)挖掘?qū)崙?zhàn)

3.1 異常處理

這里需要對函數(shù)baidu_news()的執(zhí)行進(jìn)行異常處理。

    companys = ['華能信托', '騰訊', '阿里巴巴']
    for company in companys:
        try:
            baidu_news(company)
            print(company + '百度新聞爬取成功!')
        except:
            print(company + '百度新聞爬取失??!')

3.2 24小時實(shí)時爬取

這個功能的實(shí)現(xiàn)比較簡單,只需要在程序外面套一層while True循環(huán)即可,然后可以在每一次循環(huán)執(zhí)行之后,引用time庫,執(zhí)行time.sleep()函數(shù)來讓程序每隔一段時間執(zhí)行一次。
通過前面的代碼,我們已經(jīng)能夠?qū)崿F(xiàn)24小時不間斷獲取新聞內(nèi)容,但是這里面不可避免的會爬取到重復(fù)的新聞數(shù)據(jù),這就涉及到數(shù)據(jù)去重的內(nèi)容,需要用到數(shù)據(jù)庫的相關(guān)知識,這部分內(nèi)容將在后面的章節(jié)進(jìn)行介紹,感興趣的讀者可以繼續(xù)關(guān)注。

4. 按時間順序爬取及批量爬取多頁內(nèi)容

前面的章節(jié)僅僅是爬取了百度新聞搜索結(jié)果的第一個頁面的內(nèi)容,消息數(shù)據(jù)不全面,本章將會介紹批量爬取多頁內(nèi)容的方法。

4.1 按時間順序爬取百度新聞

這里不涉及代碼修改的內(nèi)容,因?yàn)榘俣刃侣勀J(rèn)是按照“按焦點(diǎn)順序”排列新聞內(nèi)容,這里我們可以在搜索結(jié)果頁面的右上角選擇“按時間排序”按鈕,然后修改一下url即可。

4.2 一次性批量爬取多頁內(nèi)容

如果要實(shí)現(xiàn)爬取多頁內(nèi)容,我們需要分析每一頁網(wǎng)址的差別。
第一頁內(nèi)容的網(wǎng)址為。

https://www.baidu.com/s?tn=news&rtt=1&bsst=1&cl=2&wd=阿里巴巴

第二頁內(nèi)容的網(wǎng)址為。

https://www.baidu.com/s?tn=news&rtt=1&bsst=1&cl=2&wd=阿里巴巴&pn=10

第二頁內(nèi)容的網(wǎng)址為。

https://www.baidu.com/s?tn=news&rtt=1&bsst=1&cl=2&wd=阿里巴巴&pn=20

通過對比可以發(fā)現(xiàn),頁面網(wǎng)址之間的差別就在&pn=XX,這里可以確定第一頁的網(wǎng)址后面可以加上內(nèi)容&pn=0,因此,可以對代碼進(jìn)行如下修改。

def baidu_news(company, page):
    """
    獲取網(wǎng)頁源碼,并提取百度新聞標(biāo)題、網(wǎng)址、日期和來源
    :param company: 公司名稱
    :param page: 需要爬取的頁面的數(shù)量
    :return: 網(wǎng)頁源碼
    """
    num = (page - 1) * 10

    url = 'https://www.baidu.com/s?rtt=1&bsst=1&cl=2&tn=news&word=' + company + '&pn=' + str(num)

    res = requests.get(url, headers=headers, timeout=10)
    web_text = res.text
    # 此處省略了數(shù)據(jù)提取、清洗和爬取的代碼

def main():
    companys = ['華能信托', '騰訊', '阿里巴巴']
    for company in companys:
        for i in range(5):      # 爬取5頁內(nèi)容
            try:
                baidu_news(company, i+1)
                print(company + str(i+1) + '頁新聞爬取成功!')
            except:
                print(company + str(i+1) + '頁新聞爬取失??!')

5. 搜狗新聞與新浪財經(jīng)數(shù)據(jù)挖掘?qū)崙?zhàn)

這里采取的方法與爬取百度新聞的方法類似。

5.1 搜狗新聞數(shù)據(jù)爬取

  1. 首先獲取搜狗新聞的網(wǎng)址,我們在搜狗新聞中搜索“阿里巴巴”,獲得網(wǎng)址為(經(jīng)過刪減):

https://news.sogou.com/news?query=阿里巴巴

  1. 完整代碼如下:
"""
    作者:Aidan
    時間:30/01/2020
    功能:爬取搜狗新聞數(shù)據(jù)
"""

import requests
import re

# 百度新聞網(wǎng)站只認(rèn)可瀏覽器發(fā)送的請求,所以需要設(shè)置headers參數(shù),
# 以模擬瀏覽器的發(fā)送請求,chrome瀏覽器可以通過about:version獲取
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                         'AppleWebKit/537.36 (KHTML, like Gecko) '
                         'Chrome/77.0.3865.120 Safari/537.36'}

def sougou_news(company, page):
    """
    獲取網(wǎng)頁源碼,并提取搜狗新聞標(biāo)題、網(wǎng)址、日期和來源
    :param company: 公司名稱
    :param page: 需要爬取的頁面的數(shù)量
    :return: 網(wǎng)頁源碼
    """

    url = 'https://news.sogou.com/news?query=' + company + '&page=' + str(page)

    res = requests.get(url, headers=headers, timeout=10)    # 當(dāng)訪問網(wǎng)址10秒沒有響應(yīng)時,就會停止訪問。timeout=10
    web_text = res.text

    # 獲取新聞日期
    pattern_date = '<p class="news-from">.*?&nbsp;(.*?)</p>'
    date = re.findall(pattern_date, web_text, re.S)  # re.S用于考慮換行符,因?yàn)?和*不包含換行符
    # print(info)

    # 獲取新聞的網(wǎng)址和標(biāo)題
    pattern_herf = '<h3 class="vrTitle">.*?<a href="(.*?)"'
    href = re.findall(pattern_herf, web_text, re.S)
    # print(href)

    pattern_title = '<h3 class="vrTitle">.*?>(.*?)</a>'
    title = re.findall(pattern_title, web_text, re.S)
    # print(title)

    # 數(shù)據(jù)清洗
    for i in range(len(title)):
        title[i] = re.sub('<.*?>', '', title[i])
        title[i] = re.sub('&.*?;', '', title[i])
        date[i] = re.sub('<.*?>', '', date[i])

    file_ = open('搜狗數(shù)據(jù)挖掘報告.txt', 'a')     #追加模式,不清除原來的數(shù)據(jù)
    file_.write(company + str(i+1) + '頁新聞數(shù)據(jù):' + '\n' + '\n')
    for i in range(len(title)):
        file_.write(str(i+1) + '.' + title[i] + '(' + date[i] + ')' + '\n')
        file_.write(href[i] + '\n')

    file_.write('————————————————————————————————————————————' + '\n' + '\n')
    file_.close()

def main():
    companys = ['華能信托', '騰訊', '阿里巴巴']
    for company in companys:
        for i in range(5):      # 爬取5頁內(nèi)容
            try:
                sougou_news(company, i+1)
                print(company + str(i+1) + '頁新聞爬取成功!')
            except:
                print(company + str(i+1) + '頁新聞爬取失??!')

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容