Python爬虫实例--爬取人民网新闻
引用部分内容:https://blog.csdn.net/wenxuhonghe/article/details/90047081
其实我只是因为在那边评论区想评论,然后发现位置不够,所以才打算写这个博客的,然后具体的可以看我转载的文章,很详细,我这边只说一下关于txt转换为JSON格式的问题
第一次写,格式可能很乱,见谅一下
话不多说,直接开始吧
这是未修改前得到的文本样式
这里的话可以看到,爬取的文章都是按照日期整整齐齐排列的,所以看起来很舒服方便
然后有些可能就算需要json格式来进行保存
当时看了下评论区,发现有这个要求的也有,也看到了有人在下方评论写了方法
尝试了下,如下图
格式修改了是不错,不过看着好别扭(密集恐惧症的朋友就更不推荐了)
所以再尝试了下其他方法,主要是想着如果能将刚开始运行得到的文件夹里面的所有txt文件一起转
化,然后除了格式,命名啥的不变就完美了,主要是看着方便
于是网上找了一下,再请教了下我组长,得到了如下
这里面关于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,所以一些可能很简单的问题有时候都能让我懵)
如果有大佬成功合并的话可以在评论区支呼一声
上一篇: 前面那个一定要摔死