爬蟲大作業(2017年科技界發生了哪些變化——爬取17年騰訊新聞科技板塊下的所有新聞)



一、主題

  本次作業是通過爬取騰訊新聞科技板塊下2017年所有的新聞數據來分析17年科技界都發生了哪些熱門事件,通過詞雲分析得出17年度科技界最熱的詞語。

二、實現過程

  1、首先打開騰訊新聞網,進入科技頻道。然后通過瀏覽器檢查工具查看網頁源代碼,查找規律。

  

可以看出騰訊新聞科技頻道下的新聞列表網址的規律如下:

  網址前面一部分以年份和月份表示,后一部分以具體哪一天的日期表示。

  所以我通過如下代碼獲取17年騰訊科技頻道新聞的所有新聞列表頁:

# 獲取2017年所有新聞詳情頁的鏈接
def FindAll():
    newsList=[]
    for month in range(1, 13):
        for day in range(1, 29):
            if(month < 10):
                month= '0'+str(month)
            if(day<10):
                day = '0'+str(day)
            url='http://tech.qq.com/l/2017{mon}/scroll_{da}.htm'.format(mon=month,da=day)
            month= int(month)
            day= int(day)
            nextUrl=finNextPage(url)
            if nextUrl:
                getListPage(nextUrl)
            getListPage(url)

2、但由於具體哪一天到底有幾頁新聞列表頁是不確定的(如下圖,有些一天的新聞列表頁只有一頁,有些兩頁或者三頁。由於三頁的情況比較少,所以我只考慮了一頁兩頁的情況)

通過觀察網頁源代碼可知,當某天新聞列表頁存在第二頁的情況下,第二頁新聞列表頁網址是在第一頁網址基礎上追加“_2"來表示的,如下圖

 

於是有了判斷某天新聞列表頁是否存在第二頁的思路,代碼如下:

# 判斷當天新聞是否存在下一頁
def finNextPage(newsUrl):
    url=newsUrl.split(".htm")
    url = url[0] + '_2.htm'
    result=requests.get(url)
    if (result.status_code==200):
        return url

3、在爬取到了17年全天的新聞列表頁的情況下,接下來就是爬取具體新聞列表頁的所有新聞詳情的網址鏈接了

  可以看到,新聞詳情頁鏈接放在li標簽里的a標簽下,所以只需爬取a標簽的href屬性值,代碼如下:

# 獲取新聞列表頁的所有新聞鏈接
def getListPage( pageUrl):
   reslistnew = requests.get(pageUrl)
   reslistnew.encoding = 'gbk'
   souplistnew = BeautifulSoup(reslistnew.text, 'html.parser')
   for news in souplistnew.select('li'):
       if len(news.select('.pub_time'))>0:
           newsUrl=news.select('a')[0].attrs['href']
           #getNewsDetail(newsUrl)
           result = re.search('http(.*?)html', newsUrl)
           if result is None:
               print("------------------------"+newsUrl+"    -------------------------------------------")
               getNewsDetail(newsUrl)
               print("\n \n \n")

4、知道了17年所有科技新聞的詳情頁鏈接,就可以開始爬取新聞詳情正文內容為詞雲分析做准備了

通過查看源代碼,可知新聞正文放在”Cnt-Main-Article-QQ“里的P標簽下,如圖

但由於騰訊新聞種類繁多,有些是圖集新聞,沒有正文內容,如果還按照有正文的方式爬取便會出錯,而且有些新聞代碼風格也不一致,正文放的DIV名字不相同,所以要區別對待爬取,代碼如下:

# 解析新聞詳情頁的新聞發布時間、標題、正文等描述
def getNewsDetail(newsUrl):
    resd = requests.get(newsUrl)
    resd.encoding = 'gbk'
    soupd = BeautifulSoup(resd.text, 'html.parser')
    news = {}
    Cnt_Main_Article=soupd.select('.Cnt-Main-Article-QQ')
    Main_P_QQ=soupd.select('Main-P-QQ')
    if soupd.select('.rv-middle'):
        news['content']=soupd.select('h1')[0].text
    else:
        news['title'] = soupd.select('h1')[0].text
        if Cnt_Main_Article:
            news['content'] = Cnt_Main_Article[0].text
        elif Main_P_QQ:
            news['content'] = ''
        else:
            news['content'] = ''
        saveNews(news['content'])
        print(news)

5、在爬取新聞正文之后,還要注意把內容保存起來,這里我把爬取到的新聞正文內容保存到TechNews.txt里。代碼如下:

# 保存新聞內容
def saveNews(content):
    f=open("TechNews.txt",'a',encoding='utf-8')
    f.write(content)
    f.close()

至此,2017年騰訊新聞科技頻道下的所有新聞正文內容已爬取下來保存好了

6、接下來就是結合詞雲進行詞頻統計了

import wordcloud

from wordcloud import wordcloud.wordCloud()

#詞雲包

import jieba
text=open('TechNews.txt','r',encoding='utf-8')
word=text.read()
text.close()
wordDict={}
wordList=list(jieba.cut(word))
wordSet=set(wordList)
wordCutSet={',','','','\n',' ','','','\u3000','','','','一個','',''}
wordSet=wordSet-wordCutSet
for w in wordSet:
    wordDict[w]=wordList.count(w)
sortWord=sorted(wordDict.items(),key=lambda e:e[1],reverse=True)
for w in range(20):
    print(sortWord[w])
    image = Image.open('stay.png')
    graph = np.array(image)
    # 進行詞雲的設置
    wc = WordCloud(font_path='./fonts/simhei.ttf',  background_color='White',max_words=230, mask=graph, random_state=30,scale=1.5)
    wc.generate_from_frequencies(keywords)
    image_color = ImageColorGenerator(graph)
    plt.imshow(wc)
    plt.imshow(wc.recolor(color_func=image_color))
    plt.axis("off")
    plt.show()
    wc.to_file('dream.png')

統計結果如下:

7、由詞雲圖可以看出,17年科技界比較火的就是大數據,人工智能,物聯網,區塊鏈等等。其中也可以看出,騰訊,谷歌,阿里巴巴,微軟,谷歌這幾家公司幾乎是占據着科技新聞的頭條,可以是科技界的大哥大了

8、最后提交爬取的全部數據、爬蟲及數據分析源代碼。

import pandas
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import re
import openpyxl

# 保存新聞內容
def saveNews(content):
    f=open("TechNews.txt",'a',encoding='utf-8')
    f.write(content)
    f.close()
# 解析新聞詳情頁的新聞發布時間、標題、正文等描述
def getNewsDetail(newsUrl):
    resd = requests.get(newsUrl)
    resd.encoding = 'gbk'
    soupd = BeautifulSoup(resd.text, 'html.parser')
    news = {}
    Cnt_Main_Article=soupd.select('.Cnt-Main-Article-QQ')
    Main_P_QQ=soupd.select('Main-P-QQ')
    if soupd.select('.rv-middle'):
        news['content']=soupd.select('h1')[0].text
    else:
        news['title'] = soupd.select('h1')[0].text
        if Cnt_Main_Article:
            news['content'] = Cnt_Main_Article[0].text
        elif Main_P_QQ:
            news['content'] = ''
        else:
            news['content'] = ''
        saveNews(news['content'])
        print(news)


# 獲取新聞列表頁的所有新聞鏈接
def getListPage( pageUrl):
   reslistnew = requests.get(pageUrl)
   reslistnew.encoding = 'gbk'
   souplistnew = BeautifulSoup(reslistnew.text, 'html.parser')
   for news in souplistnew.select('li'):
       if len(news.select('.pub_time'))>0:
           newsUrl=news.select('a')[0].attrs['href']
           #getNewsDetail(newsUrl)
           result = re.search('http(.*?)html', newsUrl)
           if result is None:
               print("------------------------"+newsUrl+"    -------------------------------------------")
               getNewsDetail(newsUrl)
               print("\n \n \n")

# 獲取2017年所有新聞詳情頁的鏈接
def FindAll():
    newsList=[]
    for month in range(1, 13):
        for day in range(1, 29):
            if(month < 10):
                month= '0'+str(month)
            if(day<10):
                day = '0'+str(day)
            url='http://tech.qq.com/l/2017{mon}/scroll_{da}.htm'.format(mon=month,da=day)
            month= int(month)
            day= int(day)
            nextUrl=finNextPage(url)
            if nextUrl:
                getListPage(nextUrl)
            getListPage(url)

# 判斷當天新聞是否存在下一頁
def finNextPage(newsUrl):
    url=newsUrl.split(".htm")
    url = url[0] + '_2.htm'
    result=requests.get(url)
    if (result.status_code==200):
        return url
    
def result():
    text=open('TechNews.txt','r',encoding='utf-8')
    word=text.read()
    text.close()
    wordDict={}
    wordList=list(jieba.cut(word))
    wordSet=set(wordList)
    wordCutSet={',','','','\n',' ','','','\u3000','','','','一個','',''}
    wordSet=wordSet-wordCutSet
    for w in wordSet:
        wordDict[w]=wordList.count(w)
    sortWord=sorted(wordDict.items(),key=lambda e:e[1],reverse=True)
    for w in range(20):
        print(sortWord[w])
        image = Image.open('stay.png')
        graph = np.array(image)
        # 進行詞雲的設置
        wc = WordCloud(font_path='./fonts/simhei.ttf',  background_color='White',max_words=230, mask=graph, random_state=30,scale=1.5)
        wc.generate_from_frequencies(keywords)
        image_color = ImageColorGenerator(graph)
        plt.imshow(wc)
        plt.imshow(wc.recolor(color_func=image_color))
        plt.axis("off")
        plt.show()
        wc.to_file('dream.png')
FindAll()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM