@[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ù)清洗
- 新聞標(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])
- 新聞來源和日期清理
提取的新聞來源和日期中存在的問題:夾雜著很多<imag>標(biāo)簽信息;新聞來源和日期連在一起;夾雜著很多換行符、制表符、空格符等
for i in range(len(info)):
info[i] = re.sub('<.*?>', '', info[i]) # 清洗<img>標(biāo)簽信息
source.append(info[i].split(' ')[0]) # 將新聞來源和日期分開
date.append(info[i].split(' ')[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(' ')[0]) # 將新聞來源和日期分開
date.append(info[i].split(' ')[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ù)爬取
- 首先獲取搜狗新聞的網(wǎng)址,我們在搜狗新聞中搜索“阿里巴巴”,獲得網(wǎng)址為(經(jīng)過刪減):
- 完整代碼如下:
"""
作者: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">.*? (.*?)</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()