整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

(京东店铺购买链接:https://item.jd.com/10038779118412.html)


码关注我

铁幕27QP27英寸电脑显示器144HZ高清游戏电竞滤蓝光护眼1ms急速响应显示屏2K英雄联盟CF 27QP黑/144HZ/升降底座【图片 价格 品牌 报价】-京东们

东商品详细的请求处理,是先显示html,然后再ajax请求处理显示价格。

1.可以运行js,并解析之后得到的html

2.模拟js请求,得到价格


如果手机显示代码错乱,发送至电脑查看。

# -*- coding: utf-8 -*-

"""

根据京东url地址,获取商品价格

京东请求处理过程,先显示html页面,然后通过ajax get请求获取相应的商品价格

1.商品的具体数据在html中的格式,如下(示例)

# product: {

# skuid: 1310118868,

# name: '\u9999\u5f71\u77ed\u88d9\u4e24\u4ef6\u5957\u88c5\u5973\u0032\u0030\u0031\u0034\u51ac\u88c5\u65b0\u6b3e\u97e9\u7248\u957f\u8896\u0054\u6064\u4e0a\u8863\u8377\u53f6\u8fb9\u534a\u8eab\u88d9\u6f6e\u0020\u85cf\u9752\u0020\u004d',

# skuidkey:'7781F505B71CE37A3AFBADA119D3587F',

# href: 'http://item.jd.com/1310118868.html',

# src: 'jfs/t385/197/414081450/336886/3070537b/541be890N2995990c.jpg',

# cat: [1315,1343,1355],

# brand: 18247,

# nBrand: 18247,

# tips: false,

# type: 2,

# venderId:38824,

# shopId:'36786',

# TJ:'0',

# specialAttrs:["is7ToReturn-1"],

# videoPath:'',

# HM:'0'

# }

2.ajax请求代码如下:

# // 获得数字价格

# var getPriceNum = function(skus, $wrap, perfix, callback) {

# skus = typeof skus === 'string' ? [skus]: skus;

# $wrap = $wrap || $('body');

# perfix = perfix || 'J-p-';

# $.ajax({

# url: 'http://p.3.cn/prices/mgets?skuIds=J_' + skus.join(',J_') + '&type=1',

# dataType: 'jsonp',

# success: function (r) {

# if (!r && !r.length) {

# return false;

# }

# for (var i = 0; i < r.length; i++) {

# var sku = r[i].id.replace('J_', '');

# var price = parseFloat(r[i].p, 10);

#

# if (price > 0) {

# $wrap.find('.'+ perfix + sku).html('¥' + r[i].p + '');

# } else {

# $wrap.find('.'+ perfix + sku).html('暂无报价');

# }

#

# if ( typeof callback === 'function' ) {

# callback(sku, price, r);

# }

# }

# }

# });

# };

"""

import urllib

import json

import re

class JdPrice(object):

"""

对获取京东商品价格进行简单封装

"""

def __init__(self, url):

self.url = url

self._response = urllib.urlopen(self.url)

self.html = self._response.read()

def get_product(self):

"""

获取html中,商品的描述(未对数据进行详细处理,粗略的返回str类型)

:return:

"""

product_re = re.compile(r'compatible: true,(.*?)};', re.S)

product_info = re.findall(product_re, self.html)[0]

return product_info

def get_product_skuid(self):

"""

通过获取的商品信息,获取商品的skuid

:return:

"""

product_info = self.get_product()

skuid_re = re.compile(r'skuid: (.*?),')

skuid = re.findall(skuid_re, product_info)[0]

return skuid

def get_product_name(self):

pass

def get_product_price(self):

"""

根据商品的skuid信息,请求获得商品price

:return:

"""

price = None

skuid = self.get_product_skuid()

url = 'http://p.3.cn/prices/mgets?skuIds=J_' + skuid + '&type=1'

price_json = json.load(urllib.urlopen(url))[0]

if price_json['p']:

price = price_json['p']

return price

# 测试代码

if __name__ == '__main__':

url = 'http://item.jd.com/1310118868.html'

url = 'http://item.jd.com/1044773.html'

jp = JdPrice(url)

print jp.get_product_price()

# htm.decode('gb2312', 'ignore').encode('utf-8')

# f = open('jjs.html', 'w')

# f.write(htm)

# f.close()

过多次双十一活动的小编表示一顿操作猛如虎,一看结果2毛5。浪费时间不说而且未必得到真正的优惠,双十一电商的“明降暗升”已经是默认的潜规则了。打破这种规则很简单,可以用 Python 写一个定时监控商品价格的小工具。

思路

  1. 第一步抓取商品的价格存入 Python 自带的 SQLite 数据库
  2. 每天定时抓取商品价格
  3. 使用 pyecharts 模块绘制价格折线图,让低价一目了然

抓取京东价格

从商品详情的页面中打开 F12 控制面板,找到包含 p.3 的链接,在旁边的 preview 面板中可以看到当前商品价格

def get_jd_price(skuId):


    sku_detail_url = 'http://item.jd.com/{}.html'
    sku_price_url = 'https://p.3.cn/prices/get?type=1&skuid=J_{}'

    r = requests.get(sku_detail_url.format(skuId)).content

    soup = BeautifulSoup(r, 'html.parser', from_encoding='utf-8')
    sku_name_div = soup.find('div', class_="sku-name")

    if not sku_name_div:
        print('您输入的商品ID有误!')
        return
    else:
        sku_name = sku_name_div.text.strip()

    r = requests.get(sku_price_url.format(skuId))
    price = json.loads(r.text)[0]['p']

    data = {
        'sku_id': skuId,
        'sku_name': sku_name,
        'price': price
    }
    return data

把抓取的价格存入 sqlite 数据库,使用 PyCharm 的 Database 功能创建一个 sqlite 数据库

最终将数据插入到数据库

# 新增
def insert(data):
    conn = sqlite3.connect('price.db')
    c = conn.cursor()
    sql = 'INSERT INTO price (sku_id,sku_name,price) VALUES ("{}", "{}", "{}")'.format(data.get("sku_id"), data.get("sku_name"), data.get('price') )
    c.execute(sql)
    conn.commit()
    conn.close()

# 查询
def select(sku_id):
    conn = sqlite3.connect('price.db')
    c = conn.cursor()
    sql = 'select sku_id, sku_name, price, time from price where sku_id = "{}" order by time asc'.format(sku_id)
    cursor = c.execute(sql)

    datas = []
    for row in cursor:
        data = {
            'sku_id': row[0],
            'sku_name': row[1],
            'price': row[2],
            'time': row[3]
        }
        datas.append(data)
    conn.close()

    return datas

示例结果

计划任务

使用轻量级的 schedule 模块每天早上 10 点抓取京东价格这一步骤

安装 schedule 模块

pip install schedule
def run_price_job(skuId):

    # 使用不占主线程的方式启动 计划任务
    def run_continuously(interval=1):
        cease_continuous_run = threading.Event()

        class ScheduleThread(threading.Thread):
            @classmethod
            def run(cls):
                while not cease_continuous_run.is_set():
                    schedule.run_pending()
                    time.sleep(interval)

        continuous_thread = ScheduleThread()
        continuous_thread.start()
        return cease_continuous_run
    
    # 每天10点运行,get_jd_price:任务方法,skuId:任务方法的参数
    schedule.every().day.at("10:00").do(get_jd_price, skuId=skuId)
    run_continuously()

查看历史价格

使用 pytharts 模块绘制折线图,直观的查看每一天的价格差异


datas = select(skuId)

def line(datas):
    x_data = []
    y_data = []
    for data in datas:
        x_data.append(data.get('time'))
        y_data.append(data.get('price'))

    (
        Line()
        .add_xaxis(x_data)
        .add_yaxis(datas[0].get('sku_name'), y_data, is_connect_nones=True)
        .render("商品历史价格.html")
    )

总结

本文抓取了京东商城的价格,小伙伴们也可以修个脚本抓取淘宝的价格。使用 Python 解决生活中的小小痛点,让钱包不再干瘪。