7*24小时全球实时财经新闻直播摘要python抓取

前言

因要研究一下经济和舆情,所以需要原始的数据,通常来说,信息的摘要已经足够,而且信息格式规整不需要进行复杂的清洗。
本程序采用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然后下载解析即可。

二、下载

1.解析函数

通过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)

2.总下载+保存

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))

3.其他

找到需要的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

4.全部代码

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())

3.自动更新

具体的设置可以百度,这里只有关键的条件,如有问题可以留言。
7*24小时全球实时财经新闻直播摘要python抓取_第1张图片
7*24小时全球实时财经新闻直播摘要python抓取_第2张图片

三、代码改进

1.可以添加多进程,下载更快
2.因为新闻是实时更新的所以会漏掉部分新闻(当你在抓取这一页后和下一页前更新了,下一页最早的一个新闻就会漏掉)
3.遍历寻找code太慢,需要二分查找。
4.可以添加其他信息源
5.文件的保存与读取效率太低(数据太小看不出来什么),浪费了格式转换的性能。

欢迎评论、建议、讨论。

你可能感兴趣的:(python,新闻提取,爬虫)