import json
import requests import pymysql url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=-1&count=10&category=111' headers = { 'Cookie': 'aliyungf_tc=AQAAALoQF3p02gsAUhVFebQ3uBBNZn+H; xq_a_token=584d0cf8d5a5a9809761f2244d8d272bac729ed4; xq_a_token.sig=x0gT9jm6qnwd-ddLu66T3A8KiVA; xq_r_token=98f278457fc4e1e5eb0846e36a7296e642b8138a; xq_r_token.sig=2Uxv_DgYTcCjz7qx4j570JpNHIs; _ga=GA1.2.516718356.1534295265; _gid=GA1.2.1050085592.1534295265; u=301534295266356; device_id=f5c21e143ce8060c74a2de7cbcddf0b8; Hm_lvt_1db88642e346389874251b5a1eded6e3=1534295265,1534295722; Hm_lpvt_1db88642e346389874251b5a1eded6e3=1534295722', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36', } while True: response = requests.get(url,headers=headers) res_dict = json.loads(response.text) next_id = res_dict['next_max_id'] next_url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id='+str(next_id)+'&count=10&category=111' url = next_url list_list = res_dict['list'] for list_item in list_list: data_str = list_item['data'] data_str = json.loads(data_str) s_id = data_str['id'] s_title = data_str['title'] s_description = data_str['description'] s_target = data_str['target'] #写入mysql db = pymysql.connect(host='127.0.0.1',user='root',password='123456',port='3306',database='xueqiu',charset='utf-8') cursor = db.cursor(www.leyouzaixian2.com) sql = "insert into iceball values (null ,'{}','{}','{}','{}')".format(s_id,s_title,s_description,s_target) cursor.execute(sql) db.commit(www.yigouyule2.cn) cursor.close() db.close(www.hjylp178.com) # 写入文件版本 # temp = str(s_id) + ' ' + str(s_title) + ' ' + str(s_description) + ' ' + s_target # print(temp) # with open('xinwen.html','a',encoding='utf-8') as f: # f.write(temp + '\n') --------------------- 这个例子和第一个例子相比,唯一不同就是ngx.say输出内容长了不少,我们发现浏览器先收到所有的hello,接着又收到了"the world" 。然而如果我们把4000改为小一点的值如2000(不同配置这个相对大小或有不同),那么仍然会出现先停顿3s,然后所有"hello"连同最后"the world"一起输出的情况。 通过以上三个例子,我们可以得出下面的结论: ngx.say和ngx.print的同步和异步 nginx有个输出缓冲(system send buffer),如16k。ngx.say和ngx.print默认是向这个输出缓冲写入数据,如果没有显示的调用ngx.flush,那么在content阶段结束后输出缓冲会写入客户端; 如果没有ngx.flush也没有到结束阶段,但如果输出缓冲区满了,那么也会输出到客户端; 因此ngx.say和ngx.print的默认向客户端的输出都是异步的,非实时性的,改变这一行为的是ngx.flush,可以做到同步和实时输出。这在流式输出,比如下载大文件时非常有用。 ngx.flush的同步和异步 lua-nginx也提到了ngx.flush的同步和异步。某一个ngx.say或者ngx.print调用后,这部分输出内容会写到输出缓冲区,同步的方式ngx.flush(true)会等到内容全部写到缓冲区再输出到客户端,而异步的方式ngx.flush()会将内容一边写到缓冲区,而缓冲区则一边将这些内容输出到客户端。 openresty和nginx流式输出的比较 流式输出,或者大文件的下载,nginx的upstream模块已经做得非常好,可以通过proxy_buffering|proxy_buffer_size|proxy_buffers 等指令精细调控,而且这些指令的默认值已经做了妥善处理。我们来看看这些指令以及默认值: proxy_buffering on; proxy_buffer_size 4k|8k; proxy_buffers 8 4k|8k; proxy_busy_buffers_size 8k|16k; proxy_temp_path proxy_temp; proxy_buffering on表示内存做整体缓冲,内存不够时多余的存在由proxy_temp_path指定的临时文件中,off表示不做任何输出缓冲,从上游响应中接收一点就向客户端输出一点 proxy_buffer_size和proxy_buffers都是指定内存缓冲区的大小,默认为一页的大小,proxy_buffers还可以指定这样的缓冲区的个数 proxy_busy_buffers_size 这个"busy"看得出,这个指令一定是用在比较繁忙的时候了。在比较繁忙的时候(高并发或者大文件下载)时,就没有必要等到上游响应全部来了再发给客户端,可以来了一部分(proxy_busy_buffers_size)就发过去。于此同时,缓冲区的另外部分可以继续读。如果内存缓冲区不够用了,还可以开启文件缓冲区 proxy_temp_path 使用文件作为接受上游请求的缓冲区buffer,当内存不够用时启用 openresty的怎么做到过大响应的输出呢? 《OpenResty 最佳实践》 提到了两种情况: 输出内容本身体积很大,例如超过 2G 的文件下载 输出内容本身是由各种碎片拼凑的,碎片数量庞大 前面一种情况非常常见,后面一种情况比如上游已经开启Chunked的传输方式,而且每片chunk非常小。笔者就遇到了一个上游服务器通过Chunked分片传输日志,而为了节省上游服务器的内存将每片设置为一行日志,一般也就几百字节,这就太“碎片”了,一般日志总在几十到几百M,这么算下来chunk数量多大10w+。笔者用了resty.http来实现文件的下载,文件总大小48M左右。 local http = require "resty.http" local httpc = http.new() httpc:set_timeout(6000) httpc:connect(host, port) local client_body_reader, err = httpc:get_client_body_reader() local res, err = httpc:request({ version = 1.1, method = ngx.var.request_method, path = ngx.var.app_uri, headers = headers, query = ngx.var.args, body = client_www.dfgjpt.com body_reader }) if not res www.hjshidpt.com then ngx.say("Failed www.huarenyl.cn to request ".www.furong157.com. ngx.var.app_name .." server: ", err) return end -- Response status ngx.status = res.status -- Response headers for k, v in pairs(res.headers) do if k ~= "Transfer-www.michenggw.com/ Encoding" then --必须删除上游Transfer-Encoding响应头 ngx.header[k] = v end end