文档章节

python爬取淘宝商品信息并加入购物车

oj8kay
 oj8kay
发布于 2017/06/19 11:43
字数 2951
阅读 1920
收藏 60
点赞 6
评论 3

先说一下最终要达到的效果:谷歌浏览器登陆淘宝后,运行python项目,将任意任意淘宝商品的链接传入,并手动选择商品属性,输出其价格与剩余库存,然后选择购买数,自动加入购物车。

在开始爬取淘宝链接之前,咱么要先做一些准备工作,我项目中使用的是 python2.7 ,开发与运行环境都是win10,浏览器是64位chrome 59.0.3。由于淘宝的模拟登陆涉及到一些复杂的UA码算法以及滑块登陆验证,能力有限,为了图省事就使用浏览器手动登录淘宝然后python获取生成的cookie的方式来爬取登录后的数据。

获取cookie

要获取登录成功后的cookie,一种办法是浏览器打开开发者工具,手动复制cookie,但是这样比较麻烦,因为淘宝里面的请求很多不是同一个域,所以发送给服务器的cookie也不一样,如果换一个地址就手动复制一次也太low了,咱们为了有big一些,直接读取chrome存储在本地的cookie,然后拼出来。

网上查了一下,chrome的中的cookie以sqlite的方式存储在 %LOCALAPPDATA%\Google\Chrome\User Data\Default\Cookies 目录下,cookie的value也经过了CryptUnprotectData加密。知道了这些,我们就可以往下走了。

这里需要用到sqlite3模块

def get_cookie(url):
    """
    获取该的可用cookie
    :param url:
    :return:
    """

    domain = urllib2.splithost(urllib2.splittype(url)[1])[0]
    domain_list = ['.' + domain, domain]
    if len(domain.split('.')) > 2:
        dot_index = domain.find('.')
        domain_list.append(domain[dot_index:])
        domain_list.append(domain[dot_index + 1:])

    conn = None
    cookie_str = None
    try:
        conn = sqlite3.connect(r'%s\Google\Chrome\User Data\Default\Cookies' % os.getenv('LOCALAPPDATA'))
        cursor = conn.cursor()
        print '-' * 50
        sql = 'select host_key, name, value, encrypted_value, path from cookies where host_key in (%s)' % ','.join(['"%s"' % x for x in domain_list])
        row_list = cursor.execute(sql).fetchall()
        print u'一共找到 %d 条' % len(row_list)
        print '-' * 50
        print u'%-20s\t%-5s\t%-5s\t%s' % (u'域', u'键', u'值', u'路径')
        cookie_list = []
        for host_key, name, value, encrypted_value, path in row_list:
            decrypted_value = win32crypt.CryptUnprotectData(encrypted_value, None, None, None, 0)[1].decode(print_charset) or value
            cookie_list.append(name + '=' + decrypted_value)
            print u'%-20s\t%-5s\t%-5s\t%s' % (host_key, name, decrypted_value, path)
        print '-' * 50
        cookie_str = '; '.join(cookie_list)
    except Exception:
        raise CookieException()
    finally:
        conn.close()
        return cookie_str, domain

get_cookie函数的开头需要获取domain_list是因为淘宝的一些请求是跨域共享cookie的,所以要把该url所有可用的cookie提取出来。然后,我们就可以拿着这个cookie去请求登陆后的数据啦。

 

设置代理

不过一般在请求数据前需要再做一件事——设置代理,使用高匿代理可以有效地避免淘宝的反爬虫机制封禁本机IP。代理的获取途径有很多,网上能找到不少免费的代理,虽然不是很稳定,不过咱们只是玩玩,就不计较这些了,随便百度了一下,找到一个www.xicidaili.com网站,咱们就爬取这个网站的高匿代理来作为我们的代理,获取成功后访问bing来测试咱们的代理是否可用。

def set_proxy():
    """
    设置代理
    """
    # 获取xicidaili的高匿代理
    proxy_info_list = []  # 抓取到的ip列表
    for page in range(1, 2):  # 暂时只抓第一页
        request = urllib2.Request('http://www.xicidaili.com/nn/%d' % page)
        request.add_header('Accept-Encoding', 'gzip, deflate')
        request.add_header('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8')
        request.add_header('Accept-Language', 'zh-CN,zh;q=0.8,en;q=0.6')
        request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36')
        response = urllib2.urlopen(request, timeout=5)

        headers = response.info()
        content_type = headers.get('Content-Type')
        if content_type:
            charset = re.findall(r"charset=([\w-]+);?", content_type)[0]
        else:
            charset = 'utf-8'
        if headers.get('Content-Encoding') == 'gzip':
            gz = gzip.GzipFile(fileobj=StringIO.StringIO(response.read()))
            content = gz.read().decode(charset)
            gz.close()
        else:
            content = response.read().decode(charset)
        response.close()
        print u'获取第 %d 页' % page
        ip_page = re.findall(r'<td>(\d.*?)</td>', content)
        proxy_info_list.extend(ip_page)
        time.sleep(random.choice(range(1, 3)))

    # 打印抓取的内容
    print u'代理IP地址\t端口\t存活时间\t验证时间'
    for i in range(0, len(proxy_info_list), 4):
        print u'%s\t%s\t%s\t%s' % (proxy_info_list[i], proxy_info_list[i + 1], proxy_info_list[i + 2], proxy_info_list[i + 3])

    all_proxy_list = []  # 待验证的代理列表
    # proxy_list = []  # 可用的代理列表
    for i in range(0, len(proxy_info_list), 4):
        proxy_host = proxy_info_list[i] + ':' + proxy_info_list[i + 1]
        all_proxy_list.append(proxy_host)

    # 开始验证

    # 单线程方式
    for i in range(len(all_proxy_list)):
        proxy_host = test(all_proxy_list[i])
        if proxy_host:
            break
    else:
        # TODO 进入下一页
        print u'没有可用的代理'
        return None

    # 多线程方式
    # threads = []
    # # for i in range(len(all_proxy_list)):
    # for i in range(5):
    #     thread = threading.Thread(target=test, args=[all_proxy_list[i]])
    #     threads.append(thread)
    #     time.sleep(random.uniform(0, 1))
    #     thread.start()
    #
    # # 等待所有线程结束
    # for t in threading.enumerate():
    #     if t is threading.currentThread():
    #         continue
    #     t.join()
    #
    # if not proxy_list:
    #     print u'没有可用的代理'
    #     # TODO 进入下一页
    #     sys.exit(0)
    print u'使用代理: %s' % proxy_host
    urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler({'http': proxy_host})))

本来是想使用多线程来验证代理可用性,当有一个测试通过后想关闭其他线程,结束验证请求,但是没找到解决办法,就暂时先用循环一个一个来验证了,有其他思路想法的小伙伴可以在留言区指教。

分析页面

接下来,我们需要获取商品每个sku所对应的价格和库存,先说一下我的分析过程,有更好的分析方法可以留言或私信交流。打开 Chrome Web Developer Tools ,输入某个淘宝商品的地址,将工具切换到Network标签,然后在标签内容中右键 - > save as HAR with content,将当前所有请求和响应的文本内容保存到本地,用编辑器打开,然后通过关键字搜索想要的东西然后分析猜测。

经过推测,淘宝中每个商品属性有一个id保存在data-value中,

通过不同的属性值可以组合成不同的“sku_key”,然后通关页面中的skuMap来获取该sku_key对应的sku信息

这里有三步比较关键

  1. 通过正则来获取页面中的skuMap数据,然后转化为python的字典对象;
  2. 对不同的属性值进行排列组合,寻找是否有sku_key(通过itertools模块的permutations函数实现)
  3. 将中文的属性名和属性值对应起来,以便于后续通过输入属性来获取sku数据

获取商品信息

def get_base_info(page_url):
    """
    从页面获取基本的参数
    :param page_url: 
    :return:
    """
    page_url = page_url.strip()
    cookie_str = get_cookie(page_url)
    print u'page cookie :', cookie_str

    request = urllib2.Request(page_url)
    request.add_header('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8')
    request.add_header('Accept-Encoding', 'gzip, deflate, br')
    request.add_header('Cookie', cookie_str)
    request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36')
    response = urllib2.urlopen(request)
    headers = response.info()
    content_type = headers.get('Content-Type')
    if content_type:
        charset = re.findall(r"charset=([\w-]+);?", content_type)[0]
    else:
        charset = 'utf-8'
    if headers.get('Content-Encoding') == 'gzip':
        gz = gzip.GzipFile(fileobj=StringIO.StringIO(response.read()))
        content = gz.read().decode(charset)
        gz.close()
    else:
        content = response.read().decode(charset)
    with open(u'.\content.html', 'w+') as page_file:
        page_file.write(content.encode(print_charset))  # 写入文件待观察
    # 获取item_id
    item_id = re.findall(r'(^|&)id=([^&]*)(&|$)', page_url[page_url.find('?'):])[0][1]
    # 获取sku_dict
    sku_map = json.loads(re.findall(r'skuMap\s*:\s*(\{.*\})\n\r?', content)[0])
    sku_dict = {}
    for k, v in sku_map.items():
        sku_dict[k] = {
            'price': v['price'],  # 非推广价
            'stock': v['stock'],  # 库存
            'sku_id': v['skuId']  # skuId
        }
    ct = re.findall(r'"ct"\s*:\s*"(\w*)",', content)[0]
    timestamp = int(time.time())
    doc = pq(content)
    # ========== 获取每个类别属性及其属性值的集合 start ==========
    prop_to_values = {}
    for prop in doc('.J_Prop ').items():
        values = []
        for v in prop.find('li').items():
            values.append({
                'name': v.children('a').text(),
                'code': v.attr('data-value')
            })
            prop_to_values[prop.find('.tb-property-type').text()] = values
    # ========== end ==========
    return {
        'ct': ct,
        'nekot': timestamp,
        'item_id': item_id,
        'prop_to_values': prop_to_values,
        'sku_dict': sku_dict
    }

这个函数取名叫get_base_info是因为经过几个案例分析,发现页面上的价格和库存并不是淘宝最后显示的数据,真实的数据需要通过https://detailskip.taobao.com/service/getData/1/p1/item/detail/sib.htm来获取,这里面包括了一些库存、推广信息。

获取可以出售的商品信息:

def get_sale_info(sib_url):
    """
    获取可以出售的商品信息
    :param sib_url: 
    :return:
    """
    cookie_str, host = get_cookie(sib_url)
    print u'sale cookie :', cookie_str

    request = urllib2.Request(sib_url)
    request.add_header('Accept', '*/*')
    request.add_header('Accept-Encoding', 'gzip, deflate, br')
    request.add_header('Accept-Language', 'zh-CN,zh;q=0.8,en;q=0.6')
    request.add_header('Connection', 'keep - alive')
    request.add_header('Cookie', cookie_str)
    request.add_header('Host', host)
    request.add_header('Referer', 'https://item.taobao.com')
    request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36')
    response = urllib2.urlopen(request)

    headers = response.info()

    # 获取字符集
    content_type = headers.get('Content-Type')
    if content_type:
        charset = re.findall(r"charset=([\w-]+);?", content_type)[0]
    else:
        charset = 'utf-8'

    if headers.get('Content-Encoding') == 'gzip':
        gz = gzip.GzipFile(fileobj=StringIO.StringIO(response.read()))
        content = gz.read().decode(charset)
        gz.close()
    else:
        content = response.read().decode(charset)
    json_obj = json.loads(content)
    sellable_sku = json_obj['data']['dynStock']['sku']  # 可以售卖的sku
    promo_sku = json_obj['data']['promotion']['promoData']  # 推广中的sku
    if promo_sku:
        for k, v in sellable_sku.items():
            promos = promo_sku[k]
            if len(promos) > 1:
                print u'有多个促销价,建议手动确认'
            price = min([float(x['price']) for x in promos])
            v['price'] = price
            # TODO amountRestriction 限购数量
    return sellable_sku

ps:不久前才发现还有限购数量的限制,不过并不影响后续加入购物车的操作,就暂时先加入TODO,以后再更新

根据用户输入获取商品单价以及库存

最后通过终端输入地址和属性获取商品信息,看看能不能成功。

def check_item():
    page_url = raw_input(u'请输入商品地址:'.encode(print_charset)).decode(print_charset)
    base_info = get_base_info(page_url)
    item_id = base_info['item_id']
    modules = ['dynStock', 'qrcode', 'viewer', 'price', 'duty', 'xmpPromotion', 'delivery', 'activity',
               'fqg', 'zjys', 'couponActivity', 'soldQuantity', 'contract', 'tradeContract']
    ajax_url = 'https://detailskip.taobao.com/service/getData/1/p1/item/detail/sib.htm?itemId=%s&modules=%s' % (item_id, ','.join(modules))
    print 'request -> ', ajax_url
    sku_dict = get_sale_info(ajax_url)
    prop_to_values = base_info['prop_to_values']
    base_info_sku_dict = base_info['sku_dict']
    info = {
        'ct': base_info['ct'],
        'nekot': base_info['nekot'],
        'item_id': base_info['item_id'],
        'prop_to_values': prop_to_values,
    }
    for k, v in sku_dict.items():
        v['sku_id'] = base_info_sku_dict[k].get('sku_id')
        if 'price' not in v.keys():
            v['price'] = base_info_sku_dict[k].get('price')
    info['sku_dict'] = sku_dict
    with open(u'.\sku.json', 'w+') as sku_file:
        sku_file.write(json.dumps(info, ensure_ascii=False).encode('utf-8'))
    code_list = []
    item_prop = raw_input(u'请输入商品类别名称(如:颜色分类,直接回车结束输入):'.encode(print_charset)).decode(print_charset)
    while item_prop:
        if item_prop in prop_to_values.keys():
            prop_values = prop_to_values[item_prop]
            sku_value = raw_input(u'请输入商品属性(如:可爱粉):'.encode(print_charset)).decode(print_charset)
            for v in prop_values:
                if v.get('name') == sku_value:
                    code_list.append(v.get('code'))
                    break
            else:
                print u'没有该属性'
        else:
            print u'没有该类别'
        item_prop = raw_input(u'请输入商品类别名称(如:颜色分类,直接回车结束输入):'.encode(print_charset)).decode(print_charset)

    sku_id = None
    price = None
    stock = None
    for x in list(permutations(code_list, len(code_list))):
        if ';' + ';'.join(map(str, x)) + ';' in sku_dict.keys():
            item_prop = ';' + ';'.join(map(str, x)) + ';'
            sku_id = sku_dict[item_prop]['sku_id']
            price = sku_dict[item_prop]['price']
            stock = sku_dict[item_prop]['stock']
            print u'%s\t%s' % (u'sku_key为:', item_prop)
            print u'%s\t%s' % (u'sku_id为:', sku_id)
            print u'%s\t%s' % (u'单价为:', price)
            print u'%s\t%s' % (u'库存为:', stock)
            break
    else:
        print u'没有该款式。'

 

加入购物车

如果以上输出没毛病,就可以正式进入下一步了,加入购物车,试着自己在浏览器上加入购物车,然后观察请求,发现请求是通过cart.taobao.com/add_cart_item.htm这个地址发送的,分析了一下关键的发送参数:

item_id —— 商品ID(页面的g_config中)
outer_id —— skuId(skuMap中)
outer_id_type —— outer_id类型,2表示outer_id传递的是skuid
quantity —— 需要加入购物车的数量
opp —— 单价
_tb_token_ —— 可以从cookie中获取
ct —— (g_config.vdata.viewer中)
deliveryCityCode —— 发货城市 (sib.htm中,暂时取默认或者不填)
nekot —— 当前时间戳

既然需要的东西都找到了,那就好办了:

def add_item_to_cart(item_id, sku_id, price, ct, nekot, tb_token, stock):
    """
    添加商品到购物车
    :param item_id: 
    :param sku_id: 
    :param price: 
    :param ct: 
    :param nekot: 
    :param tb_token: 
    :param stock: 
    :return: 
    """
    add_cart_url = 'https://cart.taobao.com/add_cart_item.htm?'
    cookie_str, host = get_cookie(add_cart_url)
    print u'cookie串:', cookie_str

    quantity = raw_input(u'请输入需要加到购物车的数量:'.encode(print_charset))
    if quantity.isdigit():
        quantity = int(quantity)
        if quantity > stock:
            print u'超过最大库存', stock
    else:
        print u'非法输入'

    params = {
        'item_id': item_id,
        'outer_id': sku_id,
        'outer_id_type': '2',
        'quantity': quantity,
        'opp': price,
        'nekot': nekot,
        'ct': ct,
        '_tb_token_': tb_token,
        'deliveryCityCode': '',
        'frm': '',
        'buyer_from': '',
        'item_url_refer': '',
        'root_refer': '',
        'flushingPictureServiceId': '',
        'spm': '',
        'ybhpss': ''
    }
    request = urllib2.Request(add_cart_url + urllib.urlencode(params))
    request.add_header('Accept', '*/*')
    request.add_header('Accept-Encoding', 'gzip, deflate, br')
    request.add_header('Accept-Language', 'zh-CN,zh;q=0.8,en;q=0.6')
    request.add_header('Connection', 'keep - alive')
    request.add_header('Cookie', cookie_str)
    request.add_header('Host', host)
    request.add_header('Referer', 'https://item.taobao.com/item.htm')
    request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36')
    response = urllib2.urlopen(request)
    headers = response.info()
    content_type = headers.get('Content-Type')
    if content_type:
        charset = re.findall(r"charset=([\w-]+);?", content_type)[0]
    else:
        charset = 'utf-8'
    http_code = response.getcode()
    if http_code == 200:
        print u'添加到购物车成功'

这里需要注意http_code=200时不一定是加入成功,如果没有登录也会返回200,后续研究后会完善。

 

————————————————

就写到这里,需要完整的代码戳这里 →→ Python淘宝爬虫程序,有兴趣的小伙伴欢迎随时过来打脸。

————————————————

项目最后更新于 2017年6月20日 ,不排除淘宝业务发生变动导致代码执行错误的可能

© 著作权归作者所有

共有 人打赏支持
oj8kay

oj8kay

粉丝 22
博文 17
码字总数 33329
作品 0
杭州
前端工程师
加载中

评论(3)

道道
道道

引用来自“道道”的评论

引用来自“Kidult”的评论

赞一个!!!

nice

那你
道道
道道

引用来自“Kidult”的评论

赞一个!!!

nice
Kidult
Kidult
赞一个!!!
5.2 高富帅python-人工智能时代

小奈:其实你们写的代码好像有不同派系的? 大仁:你是说编程语言?我来介绍下吧,我们来看下GitHub(程序员同城交友、代码协作平台)的数据,看下各种编程语言 Pull Requst的数据, Javascr...

产品经理的技术课堂 ⋅ 05/11 ⋅ 0

一个月入门Python爬虫,快速获取大规模数据

数据是创造和决策的原材料,高质量的数据都价值不菲。而利用爬虫,我们可以获取大量的价值数据,经分析可以发挥巨大的价值,比如: 豆瓣、知乎:爬取优质答案,筛选出各话题下热门内容,探索...

Python开发者 ⋅ 04/25 ⋅ 0

Python爬取淘宝美女信息

Python爬取淘宝美女信息下载本地并同时存储mysql数据库,存储数据库用到了pymysql模块,sql语句简单好用,直接上代码,源码请点链接Python-Spiders文集。 简单介绍下爬取文件结构,使用Pytho...

博行天下 ⋅ 2017/11/30 ⋅ 0

5个python爬虫教材,让小白也有爬虫可写,含视频教程!

认识爬虫   网络爬虫,如果互联网是一张蜘蛛网,网络爬虫既是一个在此网上爬行的蜘蛛,爬了多少路程即获取到多少数据。 python写爬虫的优势   其实以上功能很多语言和工具都能做,但是用...

柯西带你学编程 ⋅ 06/12 ⋅ 0

菜鸟学Python,上半年文章大汇总

一晃大半年过去了,时间过的真快啊!上半年我一共发表了原创的文章有近45篇,其中有一些是粉丝投稿的!后台总有人留言说查找历史文章不方便,怎么办?为了方便大家阅读,我把上半年的原创文章...

菜鸟学python ⋅ 昨天 ⋅ 0

Python抓取淘宝女装信息(二)

继上周的淘宝女装连衣裙信息爬虫进一步完善,进行了次级页面信息的抓取、支持多进程。 数据说明: 本次爬取淘宝女装连衣裙共8个字段信息,包括:商品ID、店铺ID、店铺地址、店铺名称、商品名...

超人 ⋅ 2016/12/18 ⋅ 0

Python3爬虫视频学习教程

大家好哈,现在呢静觅博客已经两年多啦,可能大家过来更多看到的是爬虫方面的博文,首先非常感谢大家的支持,希望我的博文对大家有帮助! 最近,主要的任务就是开发性感美女图片大全,使用p...

yangjiyue0520 ⋅ 2017/11/18 ⋅ 0

使用 Python 全栈打造淘宝客微信机器人(上)

本篇 将会涉及: Python 环境下淘宝客 API 的使用; 使用 Python 第三方模块 itchat 实现微信的登录的自动回复操作; PyQt5 的布局管理与多线程应用 1 、前言 1.1、什么是淘宝客 相信很多人都...

柯西带你学编程 ⋅ 05/21 ⋅ 0

她们不一样!python小白刚学会python竟然爬取了网上所有小姐姐的照片

如今想学python的人越来越多,无论是专业的程序员还是业余爱好者,都对python情有独钟。世界上值得学习的技能有很多,但是如果你要问我推荐哪一个,那么我会推荐一门编程语言,比如python。如...

Python学习 ⋅ 06/06 ⋅ 0

高级爬虫(一):Scrapy爬虫框架的安装

Hi 小伙伴们差不多有半个月没有更新干货了,一直有点忙,而且这中间还有曲折过程,也就没有更新文章. 但今天无论如何也要更新一篇文章,接下来是爬虫高级篇重点讲解的地方! 最近会连载Scrap...

Python绿色通道 ⋅ 04/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Linux中的端口大全

1 被LANA定义的端口 端口 名称 描述 1 tcpmux TCP 端口服务多路复用 5 rje 远程作业入口 7 echo Echo 服务 9 discard 用于连接测试的空服务 11 systat 用于列举连接了的端口的系统状态 13 d...

寰宇01 ⋅ 9分钟前 ⋅ 0

Confluence 6 如何备份存储文件和页面信息

备份的 ZIP 文件包含有 entities.xml,这个 XML 文件包含有 Confluence 的所有页面内容和存储附件的目录。 备份 Zip 文件结构 页面的附件是存储在附件存储目录中的,通过页面和附件 ID 进行识...

honeymose ⋅ 12分钟前 ⋅ 0

【每天一个JQuery特效】根据状态确定是否滑入或滑出被选元素

主要效果: 本文主要采用slideToggle()方法实现以一行代码同时实现以展开或收缩的方式显示或隐藏被选元素。 主要代码如下: <!DOCTYPE html><html><head><meta charset="UTF-8">...

Rhymo-Wu ⋅ 15分钟前 ⋅ 0

度量.net framework 迁移到.net core的工作量

把现有的.net framework程序迁移到.net core上,是一个非常复杂的工作,特别是一些API在两个平台上还不能同时支持。两个类库的差异性,通过人工很难识别全。好在微软的工程师们考虑到了我们顾...

李朝强 ⋅ 21分钟前 ⋅ 0

请不要在“微服务”的狂热中迷失自我!

微服务在过去几年一直是一个非常热门的话题(附录1)。何为“微服务的疯狂”,举个例子: 众所周知,Netflix在DevOps上的表现非常棒。Netfix可以做微服务。因此:如果我做微服务,我也将非常...

harries ⋅ 22分钟前 ⋅ 0

oAuth2 升级Spring Cloud Finchley.RELEASE踩坑分享

背景 6.19号,spring团队发布了期待已久的 Spring Cloud Finchley.RELEASE 版本。 重要变化: 基于Spring Boot 2.0.X 不兼容 Spring Boot 1.5.X 期间踩过几个坑,分享出来给大伙,主要是关于...

冷冷gg ⋅ 52分钟前 ⋅ 0

OSChina 周一乱弹 —— 理发师小姐姐的魔法

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @冰冰棒- :分享田馥甄的单曲《My Love》 《My Love》- 田馥甄 手机党少年们想听歌,请使劲儿戳(这里) @Li-Wang :哎,头发又长了。。。又要...

小小编辑 ⋅ 今天 ⋅ 8

Kafka1.0.X_消费者API详解2

偏移量由消费者管理 kafka Consumer Api还提供了自己存储offset的功能,将offset和data做到原子性,可以让消费具有Exactly Once 的语义,比kafka默认的At-least Once更强大 消费者从指定分区...

特拉仔 ⋅ 今天 ⋅ 0

NEO智能合约之发布和升级(二)

接NEO智能合约之发布和升级(一),我们接下来说说智能合约的升级功能。 一 准备工作 合约的升级需要在合约内预先设置好升级接口,以方便在升级时调用。接下来我们对NEO智能合约之发布和升级...

红烧飞鱼 ⋅ 今天 ⋅ 0

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部