京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)

整个界面可能会显得不太美观,但是我尽力让大家看得舒服一点。废话不多说。直接打开jd开始试一试。(使用的是谷歌浏览器)
一、打开京东和F12开发者模式。
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第1张图片
这里提一个小点(F12界面建议独立出来不要影响浏览器本身的页面,后面会有CSS反爬,字体反爬等)
下面打开链接登陆界面 https://passport.jd.com/new/login.aspx
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第2张图片
然后F12小框一打,找到二维码的链接
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第3张图片
其实只看这个链接然后去匹配抓取是不可行的。首先我们可以看出其中有许多的请求参数,这个需要自己多刷新几次,多看。
现在我们进入NETWORK,查看这些请求参数到底是何方神圣。
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第4张图片
然后一看,就nm个时间戳,上代码完事一拼。
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第5张图片
一个简易的小链接构建完成。这里其实已经可以获取到二维码了,但是我们在原请求中,很简单的看出还有许许多多的cookie,并且这里我没有把cookie写出来。其实不是我没写,而是在requests库中,有个session可以自动处理cookie,我们只需要按照network中顺序将二维码前面的链接中包含的set-cookie的回应的链接构建一遍然后请求,就会或得正确的cookie了。
其中的很多cookie其实没有什么鸟用,我也经过了筛选,这个就要自己去试一试了。
然后继续介绍二维码登陆。
当我们请求到了二维码图片后,在我们本地会一直像一个链接发起请求,去询问服务端我是不是已经扫了码,
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第6张图片
然后我们这边也可以构建同样的请求来达到相同的结果。
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第7张图片
然后一看,卧槽,这个token是什么东西,我是谁,我从哪来。其实这个好搞。
我们打开搜索按钮,给我找他的来源。3秒我要他的所有资料,我相信以各位的能力,怕是够呛吧。tui。应该没什么问题吧。
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第8张图片
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第9张图片
就是他了,断点一加,谁都不爱。艹,一点都不押韵。然后重新请求。
对不起搞错了。
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第10张图片
这不就是之前请求的cookie中的数据嘛,盘他
京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点)_第11张图片
这个calback就不用问了,没什么b用。
然后这两步构建完成了。其实大体上就已经完成了。再加上一个检测就完工了。最后附上代码,我写不下去了。溜了。

import requests,time,json,random
from PIL import Image
import functools
from log import logger



def parse_json(s):
    begin = s.find('{')
    end = s.rfind('}') + 1
    return json.loads(s[begin:end])

def response_status(resp):
    if resp.status_code != requests.codes.OK:
        print('Status: %u, Url: %s' % (resp.status_code, resp.url))
        return False
    return True
def check_login(func):
    """用户登陆态校验装饰器。若用户未登陆,则调用扫码登陆"""

    @functools.wraps(func)
    def new_func(self, *args, **kwargs):
        if not self.is_login:
            logger.info("{0} 需登陆后调用,开始扫码登陆".format(func.__name__))
            self.login_by_QRcode()
        return func(self, *args, **kwargs)

    return new_func

class User(object):
    def __init__(self):
        self.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
        self.log_url = 'https://passport.jd.com/new/login.aspx'
        self.s = requests.Session()
        self.is_login = False
        self.headers = {'User-Agent': self.user_agent}

    def _get_login_page(self):
        url = "https://passport.jd.com/new/login.aspx"
        page = self.s.get(url, headers=self.headers)
        return page

    def loging(self):
        if self.is_login:
            logger.info('登录成功')
            self.open_order_page

        self._get_login_page()
        ticket = None
        retry_times = 85
        for _ in range(retry_times):
            self.get_QR_code()
            ticket = self._get_QRcode_ticket()
            if ticket:
                break
            time.sleep(2)
        else:
           print('二维码过期,请重新获取扫描')
        if not self._validate_QRcode_ticket(ticket):
            print('二维码信息校验失败')
        print('二维码登录成功')
        self.is_login = True
        self.nick_name = self.get_user_info()
        self.open_order_page()

    def get_QR_code(self):
        QR_code_url = 'http://qr.m.jd.com/show?appid=133&size=147&t=%d'%(time.time()*1000)
        headers = {':authority': 'qr.m.jd.com',
        ':method': 'GET',
        ':path': '/show?appid=133&size=147&t=',
        ':scheme': 'https',
        'referer': 'https://passport.jd.com/new/login.aspx',
        'sec-fetch-dest': 'image',
        'sec-fetch-mode': 'no-cors',
        'sec-fetch-site': 'same-site',
        'user-agent':self.user_agent}
        response = self.s.get(url = QR_code_url,).content
        with open('QRcode.jpg','wb') as f:
            f.write(response)
        image = Image.open('QRcode.jpg')
        image.show()
        time.sleep(10)

    def _validate_QRcode_ticket(self, ticket):
        url = 'https://passport.jd.com/uc/qrCodeTicketValidation'
        headers = {
            'User-Agent': self.user_agent,
            'Referer': 'https://passport.jd.com/uc/login?ltype=logout',
        }
        resp = self.s.get(url=url, headers=headers, params={'t': ticket})

        if not response_status(resp):
            return False

        resp_json = json.loads(resp.text)
        if resp_json['returnCode'] == 0:
            return True
        else:
            logger.info(resp_json)
            return False


    def _get_QRcode_ticket(self):
        url = 'https://qr.m.jd.com/check'
        payload = {
            'appid': '133',
            'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
            'token': self.s.cookies.get('wlfstk_smdl'),
            '_': str(int(time.time() * 1000)),
        }
        headers = {
            'User-Agent': self.user_agent,
            'Referer': 'https://passport.jd.com/new/login.aspx',
        }
        resp = self.s.get(url=url, headers=headers, params=payload)
        if not response_status(resp):
            print('获取二维码扫描结果异常')
            return False

        resp_json = parse_json(resp.text)
        if resp_json['code'] != 200:
            print('Code: %s, Message: %s', resp_json['code'], resp_json['msg'])
            return None
        else:
            print('已完成手机客户端确认')
            self.is_login  = True
            a = resp_json['ticket']
            return a

    @check_login
    def open_order_page(self):
        url = 'https://order.jd.com/center/list.action'
        payload = {
            'search': 0,
            'd': 1,
            's': 4096,
        }  # Orders for nearly three months
        headers = {
            'User-Agent': self.user_agent,
            'Referer': 'https://passport.jd.com/uc/login?ltype=logout',
        }

        resp = self.s.get(url=url, params=payload, headers=headers)
        print(resp.text)
        print(self.s.cookies)

    @check_login
    def get_user_info(self):
        """获取用户信息
        :return: 用户名
        """
        url = 'https://passport.jd.com/user/petName/getUserInfoForMiniJd.action'
        payload = {
            'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
            '_': str(int(time.time() * 1000)),
        }
        headers = {
            'User-Agent': self.user_agent,
            'Referer': 'https://order.jd.com/center/list.action',
        }
        try:
            resp = self.s.get(url=url, params=payload, headers=headers)
            resp_json = parse_json(resp.text)
            # many user info are included in response, now return nick name in it
            # jQuery2381773({"imgUrl":"//storage.360buyimg.com/i.imageUpload/xxx.jpg","lastLoginTime":"","nickName":"xxx","plusStatus":"0","realName":"xxx","userLevel":x,"userScoreVO":{"accountScore":xx,"activityScore":xx,"consumptionScore":xxxxx,"default":false,"financeScore":xxx,"pin":"xxx","riskScore":x,"totalScore":xxxxx}})
            return resp_json.get('nickName') or 'jd'
        except:
            return 'jd'






a = User()
a.loging()

还有一个配置代码好用且免费。

#!/usr/bin/env python
# -*- encoding=utf8 -*-
import logging
import logging.handlers

LOG_FILENAME = 'jd-assistant.log'

logger = logging.getLogger()


def set_logger():
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')

    console_handler = logging.StreamHandler()
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)

    file_handler = logging.handlers.RotatingFileHandler(
        LOG_FILENAME, maxBytes=10485760, backupCount=5, encoding="utf-8")
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)


set_logger()

相当于做个笔记了,后面可以自行增加cookie序列来成功完成自动登陆,自动下单的任务就简单多了。仅做学习交流使用,如有任何侵权随时删除。

你可能感兴趣的:(京东模拟登陆,仅实现登陆功能(仅交流学习使用,爬虫起点))