爬虫 新闻网站 并存储到CSV文件 以红网为例 V2.0 (控制台版)升级自定义查询关键词、时间段,详细注释

发布于:2024-04-05 ⋅ 阅读:(160) ⋅ 点赞:(0)

爬虫:红网网站, 获取指定关键词与指定时间范围内的新闻,并存储到CSV文件 V2.0(控制台版)

爬取目的:为了获取某一地区更全面的在红网已发布的宣传新闻稿,同时也让自己的工作更便捷

对比V1.0升级的内容:可自定义输入查询的关键词、自定义获取的时间段内的新闻,这样大家都可以用

环境:Pycharm2021,Python3.10,

安装的包:requests,csv,bs4,datetime

代码运行结果示例:

爬虫完整代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/4/4 21:36
# @Author : LanXiaoFang
# @Site :
# @File : RedNet.py
# @Software: PyCharm
import csv
import requests
from bs4 import BeautifulSoup
import datetime

header = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept - Encoding': 'gzip, deflate, br',
    "Accept - Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
    'Connection': "keep - alive",
    'Referer': 'https://news-search.rednet.cn/Search?q=%E5%8F%8C%E7%89%8C',
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0",
    "Cookie": "wdcid=7486a2c50eaf8af8; Hm_lvt_c96b65e9975fa39afbd5e90222af5f39=1711378746,1711528844; Hm_lvt_aaecf8414f59c3fb0127932014cf53c7=1711378746,1711528844; __jsluid_s=56e0acf3607072cce852b9d4fc556f54; Hm_lpvt_c96b65e9975fa39afbd5e90222af5f39=1711528844; Hm_lpvt_aaecf8414f59c3fb0127932014cf53c7=1711528844; __jsl_clearance_s=1711530480.242|1|%2F%2BG2WNMEpLXiwlUgRr2hiMkP%2BMg%3D",
    "Upgrade-Insecure-Requests": "1",
}

article_Num_area = 1  # 用于计在标题含指定区域的存储的表中的数据的序号
article_Num = 1  # 用于计在标题不含但内容含指定区域的存储的表中的数据的序号
get_go = 0  # 获取第几页开始的数据,现在是0开始
count = 0  # 用于计算总共爬取的新闻数量

"""------Start Set 这一部分是自定义选项 查找自定义新闻------"""
# 爬取指定区域的文章 或者关键词  比如:双牌 双牌县 优化营商环境······
print("爬取指定区域的文章 或者关键词  比如:双牌 双牌县 优化营商环境")
# area = '双牌'
area = input("请输入想要搜索的关键词")

# 时间设定
# 想要获取的时间段 是个闭区间  年月日 xxxx-xx-xx
print("请输入你想要获取的时间段 是个闭区间  年月日 xxxx xx xx,例如2024 3 4")
start_time = input("请输入起始时间")  # 起始时间(包含起始日期这一天)
start_time = datetime.datetime.strptime(start_time, '%Y %m %d')

end_time = input("请输入截止时间")  # 截止时间(包含截止日期这一天)
end_time = datetime.datetime.strptime(end_time, '%Y %m %d')
"""------End Set 这一部分是自定义选项 查找自定义新闻------"""

# 获取系统时间
now = datetime.datetime.now()
year = now.year  # 年
month = now.month  # 月
day = now.day  # 日

# # 创建CSV文件并写入头部信息
with open(str(month) + '红网_标题含关键词.csv', 'w', newline='', encoding='utf-8') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['序号', '新闻名称', '新闻来源', '媒体级别', '发布日期', '原文链接'])  # 根据实际情况定义列名
with open(str(month) + '红网_标题不含内容含关键词.csv', 'w', newline='', encoding='utf-8') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['序号', '新闻名称', '信息来源', '媒体级别', '发布日期', '原文链接'])  # 根据实际情况定义列名

# 相当于满足条件就是一直循环
# while get_go <= 2: # 测试时用,只获取前1-3页的新闻
while get_go >= 0:

    url = 'https://news-search.rednet.cn/Search?q=%E5%8F%8C%E7%89%8C&s=0&o=1&r=0&p=' + str(get_go)

    html_p = requests.get(url, headers=header)
    html_p.encoding = 'utf-8'

    get_go += 1

    if html_p.status_code == 200:
        soups = BeautifulSoup(html_p.text, 'html.parser')
        article_info = soups.find_all('div', class_='result')
        # print(len(article_info), '\n')
        for i in article_info:
            result_info = i.find_all('div', class_='result-info')
            station_source = result_info[0].select('span')  # 选择result_info下的所有span标签
            station_info = station_source[0].text  # 文章发布站点
            source_info = station_source[1].text  # 文章来源

            print(station_info, source_info)
            # print(i.find_all('div', class_='title'), '\n')
            title_info = i.find_all('div', class_='title')
            # 文章链接
            article_href = title_info[0].a.get('href')
            print(article_href)

            # 升级版2.0,这一部分注释掉了,考虑通过文章链接进入文章详情页面获取: 新闻来源 发布时间,这样可以避免来源分析和计算时间的日期
            if station_info[3:] == area + "新闻网":
                # print("双牌新闻网文章链接:", article_href, "---------", "https://moment.rednet.cn/pc" + article_href[22:])
                article_href = "https://moment.rednet.cn/pc" + article_href[22:]
                # 修改文章来源为红网时刻
            if 'rednet' in article_href:
                source_info = "红网"
            if 'moment.rednet' in article_href:
                source_info = "红网时刻"
            if '来源' in source_info:
                source_info = station_info[3:]

            # 文章标题
            article_title = title_info[0].h3.text
            # 获取发布时间
            article_up_time = title_info[0].span.text
            print('发布时间', article_up_time)

            """本来想直接进入文章详情页面直接获取时间的,但是介于文章来源不同每种网站的时间所在标签也不一样,由此还是决定在这里的时间信息进行处理了"""
            # 把显示为进入和昨天的时间,改为具体的日期
            # 要注意 今天对应的昨天,
            # ---如果是今天是1月1日则昨天的年月日应为上一年的12月31日要注意;
            # ---如果今天是2-12月的1日则昨天的年月日应为上一月的最后一天

            if article_up_time == '今天':
                article_up_time = str(year) + '.' + str(month) + '.' + str(day)
            elif article_up_time == '昨天':
                if day == 1:
                    if month == 1:
                        year -= 1
                        month = 12
                        day = 31
                    else:
                        month -= 1
                        if month in [3, 5, 7, 8, 10, 12]:
                            day = 31
                        elif month in [4, 6, 9, 11]:
                            day = 30
                        elif month == 2:
                            if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):  # 闰年2月
                                day = 29
                            else:
                                day = 28
                article_up_time = str(year) + '.' + str(month) + '.' + str(day - 1)
            # 修改时间显示格式,-替换为.
            else:
                # article_up_time = article_up_time[:4] + '.' + article_up_time[5:7] + '.' + article_up_time[8:10]
                article_up_time = article_up_time.replace('-', '.')

            # print(count, '--名称', article_title, '来源', source_info, '日期', article_up_time, '链接', article_href)

            # 得到这篇文章发布的时间的日期格式
            date_article_up_time = datetime.datetime.strptime(article_up_time, '%Y.%m.%d')

            # 现在有个问题怎么退出循环,时间不满足就退出:现在获取到的新闻的时间<开始时间就退出
            if date_article_up_time < start_time:
                get_go = -1
                break

            # 把满足自定义时间的新闻内容保存到csv表格中
            if start_time <= date_article_up_time <= end_time:
                count += 1
                # date_article_up_time = datetime.datetime.strftime(date_article_up_time, "%Y.%m.%d")
                print( count, '名称', article_title, '来源', source_info, '日期', date_article_up_time, '链接', article_href)

                # 把数据存入表格 根据标题或内容 是否含有 #{area} 关键词 分开存储
                if area in article_title:
                    # 这个是标题含有#{area}的
                    with open(str(month) + '红网_标题含关键词.csv', 'a', newline='', encoding='utf-8') as csvfile:
                        writer = csv.writer(csvfile)
                        writer.writerow(
                            [article_Num_area, article_title, source_info, '级', article_up_time, article_href])
                        article_Num_area += 1
                else:
                    # 这个是标题不含但是内容含有#{area}的
                    with open(str(month) + '红网_标题不含内容含关键词.csv', 'a', newline='',
                              encoding='utf-8') as csvfile:
                        writer = csv.writer(csvfile)
                        writer.writerow([article_Num, article_title, source_info, '级', article_up_time, article_href])
                        article_Num += 1


网站公告

今日签到

点亮在社区的每一天
去签到