scrapy 模拟登陆

python网络爬虫之使用scrapy自动登录网站:https://www.cnblogs.com/zhanghongfeng/p/7684415.html

Scrapy笔记(11)- 模拟登录:https://blog.csdn.net/sdulsj/article/details/52984874

python爬虫之scrapy模拟登录:https://www.cnblogs.com/lei0213/p/8203521.html

Requests and Responses 官方参考文档:https://doc.scrapy.org/en/1.3/topics/request-response.html


一帧网不登录的时候,“排行榜单”可以查看 30条数据,登录之后可以查看 100条数据。


首先打开 fiddler(fiddler介绍及使用教程:https://blog.csdn.net/freeking101/article/category/6531758),如图:



然后打开一帧的登录页面,输入账号、密码,点击创作者登录,如图:


登录之后在打开 fiddler ,发现 fiddler 已经抓取了从登录到登录成功后的所有http 包,如图:


登录的 URL 找到了,还有发送的 post 数据找到了,下面就是写代码模拟 post 请求登录了。

只要登录后,就可以访问登录后任意一个页面。

现在我需要的数据是“热度榜单”,通过fiddle 抓包 和对比 网页上显示数据,需要的数据如图所示:



把 fiddle 抓取到的 json 数据复制下来,然后随便找一个 “json 在线解析工具”粘贴上去,就可以看到结果。

 

展开上面的 list 节点,可以看到 有 100条数据,因展开太长,截图没有展开。



模拟登陆 一帧网 示例代码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-


import scrapy
import time
import json


class SlaveSpider(scrapy.Spider):
    name = "master_yizhen"
    start_urls = ['http://www.1zhen.com/api/user/login']
    main_url = 'http://www.1zhen.com/account'
    login_url = start_urls[0]

    login_headers = {
        'Host': 'www.1zhen.com',
        "Connection": "keep-alive",
        'Accept': 'application/json, text/plain, */*',
        'X-Requested-With': 'XMLHttpRequest',
        'Origin': 'http://www.1zhen.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) '
                      'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36',
        'Content-Type': 'application/json;charset=UTF-8',
        'Referer': 'http://www.1zhen.com/account',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }

    form_data = {
        "mobile": "12345678901",  # 抓取 的 登陆的账号(手机号)
        "password": "加密密码",    # 抓取 的 加密的密码
        "role": "author"
    }

    def __init__(self):
        super(SlaveSpider, self).__init__()
        self.__base_url = 'http://www.1zhen.com'

    def start_requests(self):
        '''
        # 如果登录 url 在浏览器中能打开,也可以使用这个方法进行登录
        yield scrapy.Request(
            url=self.login_url,
            headers=self.login_headers,
            meta={'cookiejar': 1},
            callback=self.login,       #  登录函数
        )
        '''
        # 如果登录 url 在浏览器中打开返回 404 ,则只有使用下面。
        # 一帧网(http://www.1zhen.com/)登录页面(http://www.1zhen.com/api/user/login)就属于返回 404这种类型

        yield scrapy.Request(
            url=self.login_url,
            headers=self.login_headers,
            meta={'cookiejar': 1},
            callback=self.after_login,
            method='post',                   # 设置请求方法为 post 请求
            body=json.dumps(self.form_data)  # 设置请求体,即请求参数
        )  # 通过上面 fiddle 抓取的 请求登录 的 URL ,可以看到 请求登录的URL使用的是 post 方法

    def login(self, response):  # 这个函数使用与 当 登录页面可以访问时的情况
        print(response.url)
        print(response.text)
        form_data = {
            "mobile": "12345678901",  # 抓取 的 登录账号
            "password": "加密的密码",  # 抓取 的 加密密码
            "role": "author"
        }
        yield scrapy.FormRequest.from_response(
            response,
            formdata=form_data,
            headers=self.login_headers,
            meta={'cookiejar': response.meta['cookiejar']},
            callback=self.after_login,
        )

    def after_login(self, response):
        print(response.url)
        t = time.localtime(time.time())
        week_time = '{0}-{1}-{2}'.format(t.tm_year, t.tm_mon, t.tm_mday)
        page_url = '{0}/api/rank/author?during=week&pt_week={1}&platform=all&category=1'.format(
            self.__base_url,
            week_time
        ) # 构造请求的 URL
        yield scrapy.Request(
            url=page_url,
            headers=self.login_headers,
            meta={'cookiejar': response.meta['cookiejar']},
            callback=self.parse_data
        )  # 通过上面 fiddle 抓包,可以看到请求的 URL 使用的 get 方法
        pass

    def parse_data(self, response):
        data = json.dumps(response.text, ensure_ascii=False, indent=4)
        print(data)
        pass

运行结果截图:



网上找的一个使用 scrapy 模拟登录的示例代码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-


import scrapy
from scrapy import FormRequest, Request


class ExampleLoginSpider(scrapy.Spider):
    name = "login_"
    allowed_domains = ["example.webscraping.com"]
    start_urls = ['http://example.webscraping.com/user/profile']
    login_url = 'http://example.webscraping.com/places/default/user/login'

    def parse(self, response):
        print(response.text)

    def start_requests(self):
        yield scrapy.Request(self.login_url, callback=self.login)

    def login(self, response):
        form_data = {
            'email': '[email protected]',
            'password': '12345678'
        }
        yield FormRequest.from_response(response, formdata=form_data, callback=self.parse_login)

    def parse_login(self, response):
        # print('>>>>>>>>'+response.text)
        if 'Welcome Liu' in response.text:
            yield from super().start_requests()



上面是使用 scrapy 进行模拟登录

现在不使用scrapy 这个框架,使用 python 的 requests 这个牛逼的模块进行模拟登录,并把数据存到本地 redis  里面

代码如下:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author      : 
# @File        : general.py
# @Software    : PyCharm
# @description : 

import requests
import json
import redis
import hashlib
import time


class OneZhen(object):
    def __init__(self):
        self.__custom_headers = {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6",
            "Cache-Control": "max-age=0",
            "Connection": "keep-alive",
            "Content-Type": "application/x-www-form-urlencoded",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36",
            "Referer": "http://www.1zhen.com/account",
            "Host": "www.1zhen.com",
        }
        self.__post_data = {
            "mobile": "12345678901",   # 登录的账号
            "password": "加密的密码",   # 加密的密码
            "role": "author",
        }
        self.__login_url = 'http://www.1zhen.com/api/user/login'
        self.__base_url = 'http://www.1zhen.com'
        self.data = None
        self.__session = requests.session()    # 定义 session 会话(session可以自动管理cookies, scrapy貌似需要通过meta传递cookies)
        self.__session.headers = self.__custom_headers  # 设置请求头

    def login_onezhen(self, week_time):
        r = self.__session.post(self.__login_url, self.__post_data)
        if r.status_code == 200:
            # print(r.content)
            page_url = '{0}/api/rank/author?during=week&pt_week={1}&platform=all&category=1'.format(self.__base_url, week_time)
            page_content = self.__session.get(url=page_url)
            json_data = page_content.content.decode('utf-8')
            self.data = json.loads(json_data)
        else:
            print('login fail and status_code is {0}'.format(r.status_code))
        return self.data

    def get_data(self, week_time):
        return self.login_onezhen(week_time)


redis_host = '127.0.0.1'
redis_port = 6379
r_db = redis.Redis(host=redis_host, port=redis_port, db=0)


def write_redis(key, data_dict):
    r_db.hmset(key, data_dict)
    pass


def main():
    # current_time = '2018-06-19'
    t = time.localtime(time.time())
    current_time = '{0}-{1}-{2}'.format(t.tm_year, t.tm_mon, t.tm_mday)
    onezhen = OneZhen()
    data = onezhen.get_data(current_time)
    print('from yizhen get data success and write redis...')
    for d in data['data']['list']:
        # key = md5(d['author']['name'])
        user_name = d['author']['name']
        user_info = dict(
            name=user_name,
            head_img_url_yizhen=d['author']['avatar'],
            category=d['author']['category']
        )
        write_redis(d['author']['name'], user_info)
    print('write  redis success and exit')


def md5(src):
    m = hashlib.md5()
    m.update(src.encode('UTF-8'))
    return m.hexdigest()


if __name__ == "__main__":
    main()
    pass



通过 Redis Desktop Manager 连接到本地 Redis ,可以看到本地 Redis 里面的数据。






猜你喜欢

转载自blog.csdn.net/freeking101/article/details/80752472