0.安装包

cachetools              3.1.1       
celery                  3.1.26.post2
celery-with-redis       3.0         
certifi                 2019.9.11   
Django                  2.2.6       
django-allauth          0.40.0      
django-appconf          1.0.3       
django-celery           3.3.1       
django-celery-results   1.0.0       
django-compressor       2.3         
django-contrib-comments 1.9.1       
django-cors-headers     3.1.1       
django-crispy-forms     1.8.0       
django-environ          0.4.5       
django-filter           2.2.0       
django-fluent-comments  2.1         
django-formtools        2.1         
django-haystack         2.8.1       
django-import-export    1.2.0       
django-markdownx        2.0.28      
django-redis            4.10.0      
django-redis-cache      2.1.0       
django-redis-sessions   0.6.1       
django-rest-auth        0.9.5       
django-rest-framework   0.1.0       
django-reversion        3.0.4       
django-tag-parser       3.1         
django-taggit           1.1.0       
django-test-plus        1.3.1       
django-tinymce          2.8.0       
django-validator        0.2.7       
djangorestframework     3.10.3      
djangorestframework-jwt 1.11.0      
flower                  0.9.3       
PyMySQL                 0.9.3       
redis                   2.10.6              
tornado                 5.1.1  

1.celery设置

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'steam_user',  # steam
    'djcelery',    # celery  注册到应用中
    'rest_framework',
]

REDIS_HOST = '10.133.3.26'
REDIS_POST = 6379
REDIS_DATABASE = 3
REDIS_PASSWORD = ''

import djcelery

djcelery.setup_loader()
# celery中间人 redis://redis服务所在的ip地址:端口/数据库号
BROKER_URL = 'redis://:{}@{}:{}/{}'.format(REDIS_PASSWORD, REDIS_HOST, REDIS_POST, REDIS_DATABASE)
# celery结果返回,可用于跟踪结果
CELERY_RESULT_BACKEND = 'redis://:{}@{}:{}/{}'.format(REDIS_PASSWORD, REDIS_HOST, REDIS_POST, REDIS_DATABASE)
CELERY_IMPORTS = ('apps.steam_user.tasks')  # tasks 路径
CELERY_BROKER_URL = 'redis://:{}@{}:{}/{}'.format(REDIS_PASSWORD, REDIS_HOST, REDIS_POST, REDIS_DATABASE)

# celery内容等消息的格式设置
CELERY_ACCEPT_CONTENT = ['application/json', ]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

# celery时区设置,使用settings中TIME_ZONE同样的时区
CELERY_TIMEZONE = 'Asia/Shanghai'

  

2.在项目目录下创建celery.py文件  与setting.py同级目录

from __future__ import absolute_import, unicode_literals

from celery import Celery
from django.conf import settings
from os import path, environ

project_name = path.split(path.dirname(__file__))[-1]  # okr_manage
project_settings = "{}.settings".format(project_name)
# 设置环境变量
environ.setdefault("DJANGO_SETTINGS_MODULE", project_settings)

# 实例化Celery
app = Celery(project_name)

# 使用django的settings文件配置celery
app.config_from_object("django.conf:settings")

# Celery加载所有注册的应用
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print("Request: {0!r}".format(self.request))

3.在应用下创建tasks.py文件

from __future__ import absolute_import, unicode_literals
import time, requests, json, hashlib
from celery import task, shared_task
from apps.steam_user.query import game_app_query, achievement_query, delete_games_query, steam_friends_query, \
    delete_friends_query, steam_wishlist_query, delete_wishlist_query
from spider_user.settings import MD5_KEY
from apps.steam_user.request_data import user_info


@shared_task()   # 装饰
def steam_game_app(user_id, body):   # 游戏  游戏成就
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", }
    response = requests.get(
        url='http://api.steampowered.com/IPlayerService/GetOwnedGames/v1?key=23241F06EEB8234C46D8F390A718F71F&steamid={}&include_appinfo=true&include_played_free_games=true'.format(
            user_id),
        headers=headers, verify=False).content.decode('utf-8')
    app_origin_id_lists = []
    data_dict = json.loads(response)
    if data_dict['response']:
        for data in data_dict['response']['games']:
            item = {}
            item['steamid'] = user_id
            item['appid'] = data['appid']
            app_origin_id_lists.append(item['appid'])
            item['create_time'] = time.strftime("%Y-%m-%d %X")
            item['play_tim'] = data['playtime_forever']
            try:
                item['last_run_time'] = data['playtime_2weeks']
            except:
                item['last_run_time'] = 0
            game_app_query(item)
            achievement_response = requests.get(
                url='http://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v1/?key=23241F06EEB8234C46D8F390A718F71F&steamid={}&appid={}&l=schinese'.format(
                    user_id, item['appid']),
                headers=headers, verify=False).content.decode('utf-8')
            data_dict = json.loads(achievement_response)
            try:
                data_list = data_dict['playerstats']['achievements']
            except:
                data_list = []
            for data in data_list:
                item['is_finish'] = data['achieved']
                item['english_name'] = data['apiname']
                item['achieve_name'] = data['name'].replace('"', '“')
                item['achieve_time'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['unlocktime'])))
                achievement_query(item)
        if app_origin_id_lists:
            print(app_origin_id_lists)
            print('*' * 100)
            item = {}
            item['steamid'] = user_id
            item['spider_member_app_list'] = app_origin_id_lists
            delete_games_query(item)
        item = {
            'code': 0,
            'message': '抓取成功'.encode("utf-8").decode("latin1"),
            'body': body['body'],
        }
        local_time = str(int(time.time() * 1000))
        md_data = '{}&{}&{}'.format(json.dumps(body, ensure_ascii=False), MD5_KEY, local_time).replace(' ', '')
        access_token = hashlib.md5(md_data.encode('utf-8')).hexdigest()
        headers = {
            'Content-Type': 'application/json',
            'time': local_time,
            'accessToken': access_token,
            'isTimer': 'False'
        }
        requests.post(url='http://10.133.3.144:7071/spider/callback', data=json.dumps(item, ensure_ascii=False),
                      headers=headers)
        return 'ok'
    else:
        item = {
            'code': 403,
            'message': '用户设为隐私'.encode("utf-8").decode("latin1"),
            'body': body['body'],
        }
        local_time = str(int(time.time() * 1000))
        md_data = '{}&{}&{}'.format(json.dumps(body, ensure_ascii=False), MD5_KEY, local_time).replace(' ', '')
        access_token = hashlib.md5(md_data.encode('utf-8')).hexdigest()
        headers = {
            'Content-Type': 'application/json',
            'time': local_time,
            'accessToken': access_token,
            'isTimer': 'False'
        }
        requests.post(url='http://10.133.3.144:7071/spider/callback', data=json.dumps(item, ensure_ascii=False),
                      headers=headers)
        return 'ok'


@shared_task()
def steam_friends(user_id, body):   # 用户好友
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", }
    response = requests.get(
        url='http://api.steampowered.com/ISteamUser/GetFriendList/v1/?key=23241F06EEB8234C46D8F390A718F71F&steamid={}'.format(
            user_id),
        headers=headers, verify=False).content.decode('utf-8')

    if json.loads(response):
        friends_list = []
        for data in json.loads(response)['friendslist']['friends']:
            item = {}
            item['steamid_pid'] = user_id
            item['steamid'] = data['steamid']
            friends_list.append(item['steamid'])
            item['relationship'] = data['relationship']
            item['friend_since'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['friend_since'])))
            item['create_time'] = time.strftime("%Y-%m-%d %X")
            data = user_info(item)
            item['personaname'] = data['personName']
            item['avatarfull'] = data['headPortrait184']
            steam_friends_query(item)
        if friends_list:
            item = {}
            item['steamid_pid'] = user_id
            item['friends_list'] = friends_list
            delete_friends_query(item)
        item = {
            'code': 0,
            'message': '抓取成功'.encode("utf-8").decode("latin1"),
            'body': body['body'],
        }
        local_time = str(int(time.time() * 1000))
        md_data = '{}&{}&{}'.format(json.dumps(body, ensure_ascii=False), MD5_KEY, local_time).replace(' ', '')
        access_token = hashlib.md5(md_data.encode('utf-8')).hexdigest()
        headers = {
            'Content-Type': 'application/json',
            'time': local_time,
            'accessToken': access_token,
            'isTimer': 'False'
        }
        requests.post(url='http://10.133.3.144:7071/spider/callback', data=json.dumps(item, ensure_ascii=False),
                      headers=headers)
        return 'ok'
    else:
        item = {
            'code': 403,
            'message': '用户设为隐私'.encode("utf-8").decode("latin1"),
            'body': body['body'],
        }
        local_time = str(int(time.time() * 1000))
        md_data = '{}&{}&{}'.format(json.dumps(body, ensure_ascii=False), MD5_KEY, local_time).replace(' ', '')
        access_token = hashlib.md5(md_data.encode('utf-8')).hexdigest()
        headers = {
            'Content-Type': 'application/json',
            'time': local_time,
            'accessToken': access_token,
            'isTimer': 'False'
        }
        requests.post(url='http://10.133.3.144:7071/spider/callback', data=json.dumps(item, ensure_ascii=False),
                      headers=headers)
        return 'ok'


@shared_task()
def steam_wishlist(user_id, body):   # 愿望单
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", }
    response = requests.get(
        url='https://store.steampowered.com/wishlist/profiles/{}/wishlistdata/'.format(
            user_id),
        headers=headers, verify=False).content.decode('utf-8')

    app_origin_id_list = []
    data_dict = json.loads(response)
    if data_dict:
        for data in data_dict.keys():
            item = {}
            item['steamid'] = user_id
            item['appid'] = data
            app_origin_id_list.append(item['appid'])
            item['create_time'] = time.strftime("%Y-%m-%d %X")
            item['add_time'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data_dict[data]['added'])))
            steam_wishlist_query(item)
    if app_origin_id_list:
        item = {}
        item['steamid'] = user_id
        item['spider_member_wishlist_list'] = app_origin_id_list
        delete_wishlist_query(item)
    item = {
        'code': 0,
        'message': '抓取成功'.encode("utf-8").decode("latin1"),
        'body': body['body'],
    }
    local_time = str(int(time.time() * 1000))
    md_data = '{}&{}&{}'.format(json.dumps(body, ensure_ascii=False), MD5_KEY, local_time).replace(' ', '')
    access_token = hashlib.md5(md_data.encode('utf-8')).hexdigest()
    headers = {
        'Content-Type': 'application/json',
        'time': local_time,
        'accessToken': access_token,
        'isTimer': 'False'
    }
    requests.post(url='http://10.133.3.144:7071/spider/callback', data=json.dumps(item, ensure_ascii=False),
                  headers=headers)
    return 'ok'

4.views.py中使用

from django.views import View
from django.http import HttpResponse, JsonResponse
from apps.steam_user import tasks
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from steam_user.exceptions import NotFound, BadRequest, Forbidden
from spider_user.settings import MD5_KEY
import hashlib, json, time, requests
from apps.steam_user.request_data import user_info
from django.core.cache import cache


# Create your views here.

class SteamUserState(APIView):

    def post(self, request, *args, **kwargs):
        '''
        请求用户资料状态
        '''
        post_data = request.data
        local_time = request.META.get('HTTP_TIME')
        accessToken = request.META.get('HTTP_ACCESSTOKEN')
        body = post_data
        user_id = body['body']['userId']
        print(post_data)
        if int(time.time() * 1000) - 60000000000 < int(local_time):
            md_data = '{}&{}&{}'.format(json.dumps(body, ensure_ascii=False), MD5_KEY, local_time).replace(' ', '')
            access_token = hashlib.md5(md_data.encode('utf-8')).hexdigest()
            print(access_token)
            if access_token == accessToken:
                if body['body']['platformId'] == 1 and body['body']['kind'] == 1:
                    data = user_info(user_id)
                    item = {
                        'code': 0,
                        'message': '成功',
                        'body': dict(data, **body['body']),
                    }
                    cache.set('steam_{}'.format(user_id), data['userState'])
                    return Response(item, status=status.HTTP_200_OK)
                if body['body']['platformId'] == 1 and body['body']['kind'] == 2:
                    tasks.steam_game_app.delay(user_id, body)  # 传递参数
                    item = {
                        'code': 0,
                        'message': '爬取中',
                    }
                    return Response(item, status=status.HTTP_200_OK)
                if body['body']['platformId'] == 1 and body['body']['kind'] == 3:
                    tasks.steam_wishlist.delay(user_id, body)   # 传递参数
                    item = {
                        'code': 0,
                        'message': '爬取中',
                    }
                    return Response(item, status=status.HTTP_200_OK)
                if body['body']['platformId'] == 1 and body['body']['kind'] == 4:
                    tasks.steam_friends.delay(user_id, body)   # 传递参数
                    item = {
                        'code': 0,
                        'message': '爬取中',
                    }
                    return Response(item, status=status.HTTP_200_OK)
            else:
                return Response({'code': 401, 'message': 'accessToken失效'}, status=status.HTTP_401_UNAUTHORIZED)
        else:
            return Response({'code': 401, 'message': 'accessToken失效'}, status=status.HTTP_401_UNAUTHORIZED)

5.启动项目

python3.6 manage.py runserver 10.133.3.34:8000   # 启动Django项目

python3.6 manage.py celery worker --loglevel=info   -n worker   # 启动worker   -n 取一个名词

python3.6 manage.py celery flower   -n flower  --address=0.0.0.0 --port=5555  # 启动celery flower   -n 取一个名词   --address:ip   --port:端口

访问   http://10.133.3.34:5555/  可以看到任务



runserver 192.168.107.216:8000    # 启动django服务
celery worker -B -l info     # 启动celery 任务和定时任务
celery flower    # 启动flower服务