因要研究一下经济和舆情,所以需要原始的数据,通常来说,信息的摘要已经足够,而且信息格式规整不需要进行复杂的清洗。
本程序采用json格式来保存数据因此该程序可以便捷地进行更改,只保存自己需要的部分,或者设为开机启动和定时启动,来更新自动的数据库。
原网站网址:http://finance.sina.com.cn/7x24/
网站的数据来源:Request URL: http://zhibo.sina.com.cn/api/zhibo/feed?callback=jQuery111209642919567773593_1582017910555&page=1&page_size=20&zhibo_id=152&tag_id=0&dire=f&dpc=1&pagesize=20&id=1622305&type=1&_=1582017910576/
简化后:http://zhibo.sina.com.cn/api/zhibo/feed?&page=%1&page_size=100&zhibo_id=152/
新浪提供了2014年3月5日至今的数据,可以根据自己的需要进行下载相关的数据。
每一篇文章都有一个唯一的id。
每一page最多可以返回最近的100条新闻。
可以通过控制page可以获取历史的新闻。
相同的page返回的不一定是相同的内容。
因此只要遍历page就可以找到自己需要下载那一日下page_code然后下载解析即可。
通过page_code返回news_list,news_list是100条新闻,每一条新闻是json格式,失败重试(可能进入死循环,或达到最大迭代次数(我没有发生过))。
def get_news_list(code):
try:
headers = {
"User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)",
}
url='http://zhibo.sina.com.cn/api/zhibo/feed?&page=%s&page_size=100&zhibo_id=152'%code
news_list=requests.get(url,headers = headers).text
news_list=json.loads(news_list)['result']['data']['feed']['list']#可以在这里选择自己需要保存的信息
if 'None'in str(type(news_list)):
news_list=get_news_list(code)
return news_list
except:
return get_news_list(code)
def update_news_list(code,end_code=0):
news_list=get_news_list(code)
date = news_list[99]['create_time'][:10]
index=""
last_date=""
OK=False
#找到code页最后一条信息那一天最早的一篇新闻的code和index
while(not OK):
for i in range(len(news_list)-1,-1,-1):
if news_list[i]['create_time'][:10] !=date:
date=news_list[i]['create_time'][:10]
index=i
OK=True
break
if not OK:
code-=1
news_list=get_news_list(code)
#没有下载完
while(code>end_code):
news_list_all=[]
#先把最早的那一页属于date那一天储存下来
for i in range(index,-1,-1):
news_list_all.append(news_list[i])
code-=1
news_list=list(reversed(get_news_list(code)))
#code整一页都是date那一天的
while(news_list[len(news_list)-1]['create_time'][:10] ==date and code>0):
news_list_all.extend(news_list)
code-=1
if code==end_code:
break
news_list=list(reversed(get_news_list(code)))
#如果最后一页
if code==end_code:
with open(data_path+news_list[i]['create_time'][:10]+'.json', 'w',encoding='utf-8') as f:
f.write(listToJson(news_list_all))
break
news_list=get_news_list(code)
#下一页那一整页不都是date那一天的
for i in range(len(news_list)-1,-1,-1):
if news_list[i]['create_time'][:10]==date:
news_list_all.append(news_list[i])
else:
last_date=date
date=news_list[i]['create_time'][:10]
index=i
break
with open(data_path+last_date+'.json', 'w',encoding='utf-8') as f:
f.write(listToJson(news_list_all))
找到需要的code
这里其实应该用二分查找的,但是时间紧张,如果各位有能力请在评论区帮忙补上,谢谢。
def find_fistpage_code():
code=6469#发稿日最大page_code
while(len(get_news_list(code))>0):#如果没有了返回一个空列表
code+=1
return code
def find_your_order_code(date):
code=1
while(get_news_list(code)[0]['create_time']==date):
code+=1
return code-1
保存时list转json
def listToJson(lst):
import json
import numpy as np
keys = [int(x) for x in np.arange(len(lst))]
list_json = dict(zip(keys, lst))
str_json = json.dumps(list_json, indent=2, ensure_ascii=False) # json转为string
return str_json
from urllib.request import urlopen
from requests import Request
import requests
import json
import os
data_path=' '#数据储存位置
def get_news_list(code):
try:
url='http://zhibo.sina.com.cn/api/zhibo/feed?&page=%s&page_size=100&zhibo_id=152'%code
news_list=requests.get(url,headers = headers).text
news_list=json.loads(news_list)['result']['data']['feed']['list']
if 'None'in str(type(news_list)):
news_list=get_news_list(code)
return news_list
except:
return get_news_list(code)
def listToJson(lst):
import json
import numpy as np
keys = [int(x) for x in np.arange(len(lst))]
list_json = dict(zip(keys, lst))
str_json = json.dumps(list_json, indent=2, ensure_ascii=False) # json转为string
return str_json
def update_news_list(code,end_code=0):
news_list=get_news_list(code)
date = news_list[99]['create_time'][:10]
index=""
last_date=""
OK=False
#找到code页最后一条信息那一天最早的一篇新闻的code和index
while(not OK):
for i in range(len(news_list)-1,-1,-1):
if news_list[i]['create_time'][:10] !=date:
date=news_list[i]['create_time'][:10]
index=i
OK=True
break
if not OK:
code-=1
news_list=get_news_list(code)
#没有下载完
while(code>end_code):
news_list_all=[]
#先把最早的那一页属于date那一天储存下来
for i in range(index,-1,-1):
news_list_all.append(news_list[i])
code-=1
news_list=list(reversed(get_news_list(code)))
#code整一页都是date那一天的
while(news_list[len(news_list)-1]['create_time'][:10] ==date and code>0):
news_list_all.extend(news_list)
code-=1
if code==end_code:
break
news_list=list(reversed(get_news_list(code)))
#如果最后一页
if code==end_code:
with open(data_path+news_list[i]['create_time'][:10]+'.json', 'w',encoding='utf-8') as f:
f.write(listToJson(news_list_all))
break
news_list=get_news_list(code)
#下一页那一整页不都是date那一天的
for i in range(len(news_list)-1,-1,-1):
if news_list[i]['create_time'][:10]==date:
news_list_all.append(news_list[i])
else:
last_date=date
date=news_list[i]['create_time'][:10]
index=i
break
with open(data_path+last_date+'.json', 'w',encoding='utf-8') as f:
f.write(listToJson(news_list_all))
def find_page_code():
#找到更新所需的开始code
file_list=os.listdir(data_path)
file_list=sorted(file_list)
os.remove(data_path+file_list[len(file_list)-1])
#最后一个可能不完整所以移除
file_list=os.listdir(data_path)
file_list=sorted(file_list)
with open(data_path+file_list[len(file_list)-1], 'r',encoding='utf-8') as f:
news_list=json.load(f)
data=news_list["1"]['create_time'][:10]
code=0
while 1:
code+=1
news_list=get_news_list(code)
if news_list[0]['create_time'][:10] < data:
break
return code
def find_fistpage_code():
code=6469
while(len(get_news_list(code))>0):
code+=200
while(len(get_news_list(code))<=0):
code-=50
while(len(get_news_list(code))>0):
code+=10
while(len(get_news_list(code))<=0):
code-=2
while(len(get_news_list(code))>0):
code+=1
code-=1
return code
def find_yourorder_code(date):
#格式必须是年-月-日(带0)例如:"2014-06-01"
code=1
while(get_news_list(code)[0]['create_time'][:10]==date):
code+=1
return code-1
update_news_list(find_page_code())
1.可以添加多进程,下载更快
2.因为新闻是实时更新的所以会漏掉部分新闻(当你在抓取这一页后和下一页前更新了,下一页最早的一个新闻就会漏掉)
3.遍历寻找code太慢,需要二分查找。
4.可以添加其他信息源
5.文件的保存与读取效率太低(数据太小看不出来什么),浪费了格式转换的性能。
欢迎评论、建议、讨论。