一、简述
这篇文章我们介绍获取网易抗疫新闻版块数据并对其进行保存。
二、
第一篇博客中我们已经通过抓包的方式获取了网易新闻(移动版)中的抗疫版块新闻接口:
https://gw.m.163.com/nc/api/v1/feed/static/h5-normal-list?start=0&size=10&tid=T1579658657288
我们在python中进行如下请求:
api = 'https://gw.m.163.com/nc/api/v1/feed/static/h5-normal-list'
params = {
'start': 0, # 开始索引
'size': 10, # 请求条数
'tid': 'T1579658657288' # 版块id(这里指抗疫版块)
}
req = requests.get(api, params)
print(req.text)
返回如下: 也就是说我们请求到数据了。
接下来看一下数据的格式:
'data'下的数据有两个字段,‘items’保存了请求得到的新闻,‘wap_pluginfo’下保存的是抗疫版块下的额外信息,如下:
我们暂时只关心‘items’字段下的内容,因为‘wap_pluginfo’下只保存这三个url且不变,故我们暂时不关心。
这里我先请求了10条数据,但item中共有12项,看一下有什么不同:
首先回到网页分析请求得到的新闻在哪,首先是第一条,它位于页面的最上方,比如今天:
另外第二三条数据进分析应该是当日疫情数据:
后面九条数据则是显示在页面下方的新闻,因此新闻条数为10条,且附带两条疫情数据。
那接下来我们就只需要分析获取的第1条数据和第4条开始的数据即可。
打印其键值:
除去第二三条,我们发现还有一条数据的键值有些不同,那就是第四条,而第四条数据代表的是页面下方多条新闻的第一条,该条为专题。
因为我们只需要新闻 ,所以接下来我们关注每一条新闻含有哪些信息。
首先我们看头条新闻的键有哪些:
其次是其他新闻的键:
因为我们要把这些信息存到数据库中,因此我们先找到它们中共同的键,在分析其含义:
共同包含的属性如上,头条中很多属性是其他新闻没有的,比如‘specialID’;其他新闻中也有未包含在共同属性中的属性,如'aheadBody',这些属性我们通过后面的分析觉得是否使用。
因为数据太多且对我们无用,因此我们只选择我们所需要的部分进行分析,比如新闻、图片的url,标题,支持度等等
审查元素获取新闻链接:
从上图中我们看出链接格式为https://3g.163.com/news/article/H5I0P90K0001899N.html?clickfrom=channel2018_news_newsList#offset=1
我们去掉文号后面的参数,发现仍然可以访问该新闻页。
因此我们只需要获得article后面的文章id即可。
从打印出的结果中可以看到,这个参数保存在posid中:
其他参数就根据需要获得了
分析结果如下:
接下来就是讲获得的新闻数据保存到数据库中了。(后续取出id,将url设置为主键)
接下来是将数据取出并插入数据库中,这里有一个问题,因为我们只能控制请求的条数,且不知道何时会有更新,因此请求到的数据可能存在重叠,也就是我们可能向数据库中插入已存在的数据。解决方案是:捕获插入已存在数据这个异常并忽略(因为数据已存在),其他异常则回滚:
# 'votecount',支持度
# 'replyCount',回复数
# 'postid',新闻链接(需组合)
# 'source',新闻来源
# 'mtime',发布时间
# 'imgsrc',图片链接
# 'priority',优先级
# 'title',标题
# 'digest',文摘
# 'category',分类
# url='https://3g.163.com/news/article/' + item['postid'] + '.html'
def get_news(news):
news_list = []
for item in news:
if 'postid' in item:
day = [item['postid'], item['votecount'],
item['replyCount'], item['source'], item['mtime'], item['imgsrc'], item['priority'],
item['title'], item['digest'], item['category']]
news_list.append(day)
return news_list
def insert_news(news_list):
db = pymysql.connect(host='localhost', user='root', password='#', db='epidemicplatform',
port=3306, charset='utf8')
cursor = db.cursor()
t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
sql1 = 'insert into epidemicplatform.news(url,votecount,replyCount,source,mtime,imgsrc,priority,title,digest,' \
'category)' \
'values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
for item in news_list:
try:
cursor.execute(sql1, item)
db.commit()
print('插入成功:' + item[6])
except Exception as e:
# 检查异常原因是否是感兴趣的
result1 = re.search('Duplicate entry.*key.*PRIMARY', str(e))
# 如果是,什么都不用做
# 否则(不知道是什么原因),回滚
if result1 is None:
# 如果发生错误则回滚
db.rollback()
else:
print('数据库中已存在:' + item[0] + " pass!")
# 关闭数据库连接
print("插入完成!")
db.close()
cursor.close()
至此,获取新闻并存入数据库已经全部完成,接下来就是将这些抓取数据的动作全部自动化,也就是定时获取并更新数据,这些在将之后实现。