【大数据应用技术】作业七|爬取全部的校园新闻

本次作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2941

前言

本次我爬取的是广州商学院校园新闻的全部信息,即我给出校园新闻的网址,通过网址我们可以爬取校园新闻的作者、发布时间、概述、来源等,由于新闻较多,所以在这里我使用range(41, 51)爬取41-51页的校园新闻的信息。下面,我将从几点来讲解爬取校园新闻信息的步奏,最后第七点是整个爬取的源代码以及运行结果。

1.从新闻url获取新闻详情

第一步已经完成了获取新闻信息的步奏,接着把获取到的新闻内容添加进字典中

    # 标题
    title = newSoup.select('.show-title')[0].text
    # 发布信息
    newInfo = newSoup.select('.show-info')[0].text
    # 发布时间
    newDT = newsDateTime(newInfo)
    # 作者
    author = newInfo.split()[2].lstrip('作者:')
    # 审核
    examine = newInfo.split()[3].lstrip('审核:')
    # 来源
    source = newInfo.split()[4].lstrip('来源:')
    # 获取点击次数的url
    newClick = newsClick(url)
    # 把获取到的新闻内容添加进字典中
    newsDetail = {}
    newsDetail['newsTitle'] = title
    newsDetail['newsDaTe'] = newDT
    newsDetail['newsAuthor'] = author
    newsDetail['newsExamine'] = examine
    newsDetail['newsSource'] = source
    newsDetail['newsClick'] = newClick

2.从列表页的url获取每篇新闻url

因为这里我们用的是广州商学院的校园新闻,其校园新闻列表页是每页有10篇新闻,所以我们要根据新闻页数来获取里面的每篇新闻的url。

完成第一步后,我们接着新建一个newList的空列表,使用遍历的方式获取新闻的url(即代码中的newUrl)、新闻的概述信息,并把新闻的概述信息添加进字典中,最后把字典添加到newList列表中。

newList = []
    li = newSoup.select('li')
    for new in li:
        if len(new.select('.news-list-text')) > 0:
            newUrl = new.select('a')[0]['href']
            # 获取新闻的概述信息
            newDescription = new.select('.news-list-description')[0].text
            newsDict = newsInfo(newUrl)
            # 把新闻的概述信息添加进字典中
            newsDict['newsDescription'] = newDescription
            newList.append(newsDict)

3.生成所页列表页的url并获取全部新闻

利用for循环遍历新闻41-51页的列表页的url

allNews = []
# 获取页数为range(41,51)的新闻信息
for i in range(41, 51):
    listPageUrl = 'http://news.gzcc.cn/html/xiaoyuanxinwen/{}.html'.format(i)
    allNews.extend(newsList(newsUrl))
newsTable = ps.DataFrame(allNews)
print(newsTable) # 测试输出newsTable中的信息

4.设置合理的爬取间隔

很多网站的反爬虫机制都设置了访问间隔时间,一个IP如果短时间内超过了指定的次数就会进入“冷却CD”,再加上本来爬虫就可能会给对方网站造成访问的负载压力,为了你好我也好,建议大家在爬取别的网站的时候设置合理的爬取时间间隔,这种防范既可以从一定程度上防止被封,又可以降低对方服务器的访问压力。

import time
import random
time.sleep(random.random()*3)

5.用pandas做简单的数据处理并保存成csv文件 

在本文中,我把所爬取下来的数据保存到D:sougo ewsInfo ews.csv中,执行代码如下所示:

newsTable.to_csv(r'D:sougo
ewsInfo
ews.csv',encoding='utf-8-sig')

执行结果如图所示:

下图为执行后生成的csv文件

打开生成的news.csv文件,我们可以看到里面的内容如下图所示:

6.保存到数据库

在这里,我使用的是sqlite数据库

import sqlite3

# 把获取到的校园新闻信息保存到数据库中
with sqlite3.connect('newsInfo.sqlite') as db:
    newsTable.to_sql('news', db)
    # 查找数据库中的信息并赋给selectNews
    selectNews = ps.read_sql_query('SELECT * FROM news', con=db)
    # 输出数据库中点击次数大于200的信息
    print(selectNews[selectNews['newsClick']>200])

7.程序源代码

  1 # -*- coding: UTF-8 -*-
  2 import requests
  3 from bs4 import BeautifulSoup
  4 from datetime import datetime
  5 import re
  6 import pandas as ps
  7 import sqlite3
  8 import time
  9 import random
 10 
 11 
 12 # 获取点击次数
 13 def newsClick(url):
 14     id = re.findall('(d{1,7})', url)[-1]
 15     clickUrl = 'http://oa.gzcc.cn/api.php?op=count&id={}&modelid=80'.format(id)
 16     click = requests.get(clickUrl)
 17     time.sleep(random.random() * 3) # 延迟
 18     newClick = int(click.text.split('.html')[-1].lstrip("('").rstrip("');"))  # 获取点击次数
 19     # print('点击次数:')
 20     # print(newClick) # 测试输出点击次数
 21     return newClick
 22 
 23 # 获取新闻的发布时间
 24 def newsDateTime(newInfo):
 25     newDate = newInfo.split()[0].lstrip('发布时间:')
 26     newTime = newInfo.split()[1]
 27     newDateTime = newDate + ' ' + newTime
 28     newDT = datetime.strptime(newDateTime, '%Y-%m-%d %H:%M:%S')
 29     # print('发布时间:')
 30     # print(newDT)
 31     return newDT
 32 
 33 
 34 # 获取新闻的全部信息,并形成字典
 35 def newsInfo(url):
 36     news = requests.get(url)
 37     time.sleep(random.random() * 3)  # 延迟
 38     news.encoding = 'utf-8'
 39     newSoup = BeautifulSoup(news.text, 'html.parser')
 40 
 41     # 标题
 42     title = newSoup.select('.show-title')[0].text
 43     # print('标题:'+title) # 测试输出标题
 44 
 45     # 发布信息
 46     newInfo = newSoup.select('.show-info')[0].text
 47 
 48     # 发布时间
 49     newDT = newsDateTime(newInfo)
 50 
 51     # 作者
 52     author = newInfo.split()[2].lstrip('作者:')
 53     # print(author) # 测试输出作者
 54 
 55     # 审核
 56     examine = newInfo.split()[3].lstrip('审核:')
 57     # print(examine) # 测试输出审核
 58 
 59     # 来源
 60     source = newInfo.split()[4].lstrip('来源:')
 61     # print(source) # 测试输出来源
 62 
 63     # 获取点击次数的url
 64     newClick = newsClick(url)
 65 
 66     # 内容
 67     # newContent = newSoup.select('.show-content')[0].text
 68     # print('内容:'+newContent) #测试输出内容,由于一般新闻内容都比较长,所以这里我就不输出新闻的内容了
 69 
 70     # 把获取到的新闻内容添加进字典中
 71     newsDetail = {}
 72     newsDetail['newsTitle'] = title
 73     newsDetail['newsDaTe'] = newDT
 74     newsDetail['newsAuthor'] = author
 75     newsDetail['newsExamine'] = examine
 76     newsDetail['newsSource'] = source
 77     newsDetail['newsClick'] = newClick
 78 
 79     return newsDetail;
 80 
 81 # 获取新闻列表的概述信息,并封装成列表
 82 def newsList(url):
 83     news = requests.get(url)
 84     time.sleep(random.random() * 3)  # 延迟
 85     news.encoding = 'utf-8'
 86     newSoup = BeautifulSoup(news.text, 'html.parser')
 87     newList = []
 88     li = newSoup.select('li')
 89     for new in li:
 90         if len(new.select('.news-list-text')) > 0:
 91             newUrl = new.select('a')[0]['href']
 92             # 获取新闻的概述信息
 93             newDescription = new.select('.news-list-description')[0].text
 94             newsDict = newsInfo(newUrl)
 95             # 把新闻的概述信息添加进字典中
 96             newsDict['newsDescription'] = newDescription
 97             newList.append(newsDict)
 98     return newList
 99 
100 url = 'http://news.gzcc.cn/html/2019/xiaoyuanxinwen_0322/11047.html'
101 # print(newsInfo(url)); # 测试输出newsInfo(url)中的信息
102 
103 newsUrl = 'http://news.gzcc.cn/html/xiaoyuanxinwen/'
104 # print(newsList(newsUrl)); # 测试输出newsList(newsUrl)中的信息
105 
106 # 获取新闻的总页数
107 # page = int(newSoup.select('#pages')[0].text.split('..')[1].rstrip(' 下一页 '))
108 
109 allNews = []
110 # 获取页数为range(41,51)的新闻信息
111 for i in range(41, 51):
112     listPageUrl = 'http://news.gzcc.cn/html/xiaoyuanxinwen/{}.html'.format(i)
113     allNews.extend(newsList(newsUrl))
114 newsTable = ps.DataFrame(allNews)
115 # print(newsTable) # 测试输出newsTable中的信息
116 # newsTable.sort_index(by=['newsClick'],ascending=False) # 按点击次数排名,当ascending=TRUE时是从小到大排列
117 # newsTable.sort_index(by=['newsDaTe'],ascending=False) # 按发布时间进行排名
118 
119 # 把获取到的校园新闻信息生成csv文件
120 newsTable.to_csv(r'D:sougo
ewsInfo
ews.csv',encoding='utf-8-sig')
121 
122 # 把获取到的校园新闻信息保存到数据库中
123 with sqlite3.connect('newsInfo.sqlite') as db:
124     newsTable.to_sql('news', db)
125     # 查找数据库中的信息并赋给selectNews
126     selectNews = ps.read_sql_query('SELECT * FROM news', con=db)
127     # 输出数据库中点击次数大于200的信息
128     print(selectNews[selectNews['newsClick']>200])

运行过后,控制台输出了print(selectNews[selectNews['newsClick']>200])的运行结果如下图,即输出了点击次数大于200的新闻信息。

原文地址:https://www.cnblogs.com/bhuan/p/10669679.html