欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python爬虫实例--爬取人民网新闻

程序员文章站 2022-03-19 17:08:49
Python :爬取人民日报新闻(txt格式转换为json格式)这是未修改前得到的文本样式代码如下爬取新闻部分代码这里的话我也尝试了将两部分直接合并,然后直接得到txt文件后转化得到json文件,但是一直报错,失败了文章内容转载于:Python 网络爬虫实战:爬取人民日报新闻文章_亮出锋芒,剑指苍穹-CSDN博客_python爬取 https://blog.csdn.net/wenxuhonghe/article/details/90047081其实我只是因为在那边评论区想评论,然后发现位置不够,所以...

引用部分内容:https://blog.csdn.net/wenxuhonghe/article/details/90047081

其实我只是因为在那边评论区想评论,然后发现位置不够,所以才打算写这个博客的,然后具体的可以看我转载的文章,很详细,我这边只说一下关于txt转换为JSON格式的问题

第一次写,格式可能很乱,见谅一下

话不多说,直接开始吧

这是未修改前得到的文本样式

Python爬虫实例--爬取人民网新闻

这里的话可以看到,爬取的文章都是按照日期整整齐齐排列的,所以看起来很舒服方便

然后有些可能就算需要json格式来进行保存

当时看了下评论区,发现有这个要求的也有,也看到了有人在下方评论写了方法

尝试了下,如下图

Python爬虫实例--爬取人民网新闻

格式修改了是不错,不过看着好别扭(密集恐惧症的朋友就更不推荐了)

所以再尝试了下其他方法,主要是想着如果能将刚开始运行得到的文件夹里面的所有txt文件一起转

化,然后除了格式,命名啥的不变就完美了,主要是看着方便

于是网上找了一下,再请教了下我组长,得到了如下

Python爬虫实例--爬取人民网新闻

这里面关于json格式我就简单的命名了下title部分,有其他需求的可以自己命名下

至于功能的话我觉得应该是可了的,直接全部转化,简洁方便,速度的话也快

代码如下

import json import re def txtToJson(path, out_path): # 文件路径 # path = "E:/Python/news require/data/20190502/20190502-01-01.txt" # 读取文件 with open(path, 'r', encoding="utf-8") as file: # 定义一个用于切割字符串的正则 seq = re.compile(":") result = [] # 逐行读取 for line in file: lst = seq.split(line.strip()) item = { "title": lst[0] } result.append(item) print(type(result)) # print(result) # 关闭文件 with open(out_path, 'w', encoding='utf-8') as dump_f: json.dump(result, dump_f, ensure_ascii=False, indent=4) def txtToJson_ext(): # 文件路径 # path = "E:/Python/news require/data/20190502/20190502-01-01.txt" # 读取文件 import glob import os

    out_root = './data_json' for path in glob.glob('./data/*/*.txt'): # print(path) filename = os.path.basename(path) data_dir = path.split('\\')[1] filename = f'{filename.split(".")[0]}.json' # print(filename) # print(data_dir) # 创建目录 out_dir = f'{out_root}/{data_dir}' if not os.path.exists(out_dir): os.makedirs(out_dir) out_path = f'{out_dir}/{filename}' print(out_path) def test(): # txtToJson() txtToJson_ext() if __name__ == '__main__': import fire
    fire.Fire() 

这里是转换格式部分的代码

这里的话直接运行test函数块部分就可以了

遍历了原来之前的data目录,然后生成新的文件夹将转换后的内容填入

爬取新闻部分代码

import requests import bs4 import os import datetime import time def fetchUrl(url): # 用于发起网络请求,可以访问目标URL,获取目标网页的html内容并返回 '''
    功能:访问url的网页,获取页面内容并返回
    参数:目标网页的url
    返回:目标网页的html内容
    ''' headers = { 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36' } '''
    accept 头属性能被用在浏览器响应接受的media类型,表示自己可以接受的类型
    user-agent:告诉HTTP服务器,客户端使用的操作系统和浏览器的名称和版本
    ''' r = requests.get(url, headers=headers) r.raise_for_status() # 判断是否访问成功 r.encoding = r.apparent_encoding return r.text def getPageList(year, month, day): # 爬取当天报纸的各版面的链接,将其保存为一个数组,并返回 '''
    功能:获取当天报纸的各版面的链接列表
    参数:年,月,日
    ''' url = 'http://paper.people.com.cn/rmrb/html/' + year + \ '-' + month + '/' + day + '/nbs.D110000renmrb_01.htm' html = fetchUrl(url) bsobj = bs4.BeautifulSoup(html, 'html.parser') '''
    pageList = bsobj.find('div', attrs={'id': 'pageList'}).ul.find_all(
        'div', attrs={'class': 'right_title-name'})
    网站兼容式更新
    ''' temp = bsobj.find('div', attrs={'id': 'pageList'}) if temp: pageList = temp.ul.find_all('div', attrs={'class': 'right_title-name'}) else: pageList = bsobj.find('div', attrs={ 'class': 'swiper-container'}).find_all('div', attrs={'class': 'swiper-slide'}) linkList = [] # 分析网页html结构 for page in pageList: link = page.a["href"] url = 'http://paper.people.com.cn/rmrb/html/' + \
            year + '-' + month + '/' + day + '/' + link
        linkList.append(url) return linkList def getTitleList(year, month, day, pageUrl): # 爬取当天报纸的某一版面所有文章的链接,并保存为一个数组并返回 '''
    功能: 获取报纸某一版面的文章链接列表
    参数: 年, 月, 日, 该版面的链接
    ''' html = fetchUrl(pageUrl) bsobj = bs4.BeautifulSoup(html, 'html.parser') '''
    titleList = bsobj.find('div', attrs={'id': 'titleList'}).ul.find_all('li')
    ''' temp = bsobj.find('div', attrs={'id': 'titleList'}) if temp: titleList = temp.ul.find_all('li') else: titleList = bsobj.find( 'ul', attrs={'class': 'news-list'}).find_all('li') linkList = [] for title in titleList: tempList = title.find_all('a') for temp in tempList: link = temp["href"] if 'nw.D110000renmrb' in link: url = 'http://paper.people.com.cn/rmrb/html/' + \
                    year + '-' + month + '/' + day + '/' + link
                linkList.append(url) return linkList def getContent(html): # 用于返回文章内容页,爬取文章的标题和正文,并返回 '''
    功能: 解析HTML网页,获取新闻的文章内容
    参数: HTML网页内容
    ''' bsobj = bs4.BeautifulSoup(html, 'html.parser') # 获取文章 标题 title = bsobj.h3.text + '\n' + bsobj.h1.text + '\n' + bsobj.h2.text + '\n' # print(title) # 获取文章 内容 pList = bsobj.find('div', attrs={'id': 'ozoom'}).find_all('p') content = '' for p in pList: content += p.text + '\n' # print(content) # 返回结果 标题+内容 resp = title + content return resp def saveFile(content, path, filename): # 将文章内容保存到本地指定文件夹中 '''
    功能: 将文章内容 content 保存到本地文件中
    参数: 要保存的内容,路径,文件名
    ''' # 如果没有文件夹,则自动生成 if not os.path.exists(path): os.makedirs(path) # 保存文件 with open(path + filename, 'w', encoding='utf-8') as f: f.write(content) def download_rmrb(year, month, day, destdir): # 可以根据year,month,day参数下载该天的全部报纸文章内容,并按规则保存在指定路径destdir下 '''
    功能:爬取 人民日报 网站 某年,某月,某日的新闻内容,并保存在指定目录下
    参数: 年,月,日,文件保存的根目录
    ''' pageList = getPageList(year, month, day) for page in pageList: titleList = getTitleList(year, month, day, page) for url in titleList: # 获取新闻文章内容 html = fetchUrl(url) content = getContent(html) # 生成保存的文件路径及文件名 temp = url.split('_')[2].split('.')[0].split('-') pageNo = temp[1] titleNo = temp[0] if int(temp[0]) >= 10 else '0' + temp[0] path = destdir + '/' + year + month + day + '/' fileName = year + month + day + '-' + pageNo + '-' + titleNo + '.txt' # 保存文件 saveFile(content, path, fileName) def gen_dates(b_date, days): day = datetime.timedelta(days=1) for i in range(days): yield b_date + day * i def get_date_list(beginDate, endDate): '''
    获取日期列表
    param start:开始日期
    param end:结束日期
    return:开始日期和结束日期之间的日期列表
    ''' start = datetime.datetime.strptime(beginDate, "%Y%m%d") end = datetime.datetime.strptime(endDate, "%Y%m%d") data = [] for d in gen_dates(start, (end-start).days): data.append(d) return data if __name__ == '__main__': '''
    主函数: 程序入口
    ''' # 输入起止日期,爬取之间的新闻 beginDate = input('请输入开始日期:') endDate = input('请输入结束日期:') data = get_date_list(beginDate, endDate) for d in data: year = str(d.year) month = str(d.month) if d.month >= 10 else '0' + str(d.month) day = str(d.day) if d.day >= 10 else '0' + str(d.day) download_rmrb(year, month, day, 'E:/PYTHON/news require/data') print("爬取完成: " + year + month + day) time.sleep(3) 

这里的话我也尝试了将两部分直接合并,然后直接得到txt文件后转化得到json文件,但是一直报错,失败了

(新手小白刚开始自学python,所以一些可能很简单的问题有时候都能让我懵)

如果有大佬成功合并的话可以在评论区支呼一声 

相关标签: Python 爬虫