• 爬虫大作业(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("
     
     
    ")

    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={',','','','
    ',' ','','','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("
     
     
    ")
    
    # 获取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={',','','','
    ',' ','','','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()
  • 相关阅读:
    【转】c#文件操作大全(一)
    Visual Assist安装、破解方法
    web socket多线程实时监听
    SFTP上传下载
    数据库分页代码
    JAVA H5微信分享
    Eclipse中activiti插件的安装
    HTTP请求报文和HTTP响应报文
    CodeVS 1013&1029
    Codeforces 805D/804B
  • 原文地址:https://www.cnblogs.com/weixingna/p/8974903.html
Copyright © 2020-2023  润新知