2020 年的第一天,给大家分享如何用 Python 抓取新闻联播语料库。
语料库是什么?
语料库是语料库语言学研究的基础资源,也是经验主义语言研究方法的主要资源。应用于词典编纂,语言教学,传统语言研究,自然语言处理中基于统计或实例的研究等方面。
为什么是新闻联播?
新闻联播是最权威的新闻来源,用语规范,内容涉及时政和社会的方方面面,对生活生产有着很强的指导意义。
怎么获取新闻联播语料库?
在 Tushare Pro 数据开放平台有新闻联播文本的接口,可以直接调用获取。
或者像我这样,直接自己写代码获取就好了~
版权&免责声明:该语料库收集自网络公开信息,版权归原作者所有,本人出于科研学习交流的目的进行分享,仅用于 NLP 或其他学习用途,传播后造成任何违规不当使用,责任自负。若有侵权,请后台给我留言。
数据抓取方法仅为技术理论可行性研究,并不鼓励任何人进行真实抓取。
首先分享资源吧~我已经整理好了 2019 年全年的文字稿:
https://pan.baidu.com/s/1sN6YXjVeJBNf_2OPMkTpLQ
提取码: 2438
然后我们来分享一下代码的实现思路:
首先确定数据来源。网络上其实有一些聚合了新闻联播文字稿的网站,甚至有一些结构相对清晰容易抓取,但是为了追求字字精确,我还是选择了官网而不是二道贩子。
接下来分析页面结构。
http://tv.cctv.com/lm/xwlb/
我们在页面上可以看到一个日历控件,点击相应日期以后,下面会显示该日的新闻单,一般来讲,列表中的第一个是当天的全程新闻联播,后面则是单个新闻,点进每个新闻页面会发现“相关稿件”内容。
打开 F12 调试,点击不同的日期,即可在 XHR 标签里找到历次请求,可以发现唯一的变化就是链接地址中的日期字符串。
由此确定我们的思路。
根据变化的日期 → 获取当日新闻列表 → 循环保存新闻的稿件内容
之后的工作就是很基础的爬虫操作了,唯一稍微有技术含量的地方,就在于如何生成一个日期列表。比如我们要抓取 2019 年全年的新闻,就需要生成20190101 至 20191231 之间 365 个日期列表。以前我们写过一篇文章介绍日期列表的生成,用的是 datetime 库,这次我们用 pandas 实现。
剩下的就不多说了,大家自己看代码就好了~
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import os
import pandas as pd
import time
headers = {
'Accept': 'text/html, */*; q=0.01',
'Referer': 'http://tv.cctv.com/lm/xwlb/',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
}
def href(date):
"""
用于获取某天新闻联播各条新闻的链接
:param date: 日期,形如20190101
:return: href_list: 返回新闻链接的列表
"""
href_list = []
response = requests.get('http://tv.cctv.com/lm/xwlb/day/' + str(date) + '.shtml', headers=headers)
bs_obj = BeautifulSoup(response.text, 'lxml')
lis = bs_obj.find_all('li')
for each in lis:
href_list.append(each.find('a')['href'])
return href_list
def news(url):
print(url)
response = requests.get(url, headers=headers, )
bs_obj = BeautifulSoup(response.content.decode('utf-8'), 'lxml')
if 'news.cctv.com' in url:
text = bs_obj.find('div', {'id': 'content_body'}).text
else:
text = bs_obj.find('div', {'class': 'cnt_bd'}).text
return text
def datelist(beginDate, endDate):
# beginDate, endDate是形如‘20160601’的字符串或datetime格式
date_l = [datetime.strftime(x, '%Y%m%d') for x in list(pd.date_range(start=beginDate, end=endDate))]
return date_l
def save_text(date):
f = open(str(date) + '.txt', 'a', encoding='utf-8')
for each in href(date)[1:]:
f.write(news(each))
f.write('\n')
f.close()
for date in datelist('20190101', '20191231'):
save_text(date)
time.sleep(3)
最后,还是祝大家 2020 新年快乐~
希望大家在新的一年,学有所得,学有所成,实现每个小目标。