python 模拟登录豆瓣 并 发表动态:https://blog.csdn.net/freeking101/article/details/65445551
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
使用 url + 用户名 和 密码形式登录(使用 scrapy 框架)
一帧网不登录的时候,“排行榜单”可以查看 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 jsonclass 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) # 构造请求的 URLyield scrapy.Request(url=page_url,headers=self.login_headers,meta={'cookiejar': response.meta['cookiejar']},callback=self.parse_data) # 通过上面 fiddle 抓包,可以看到请求的 URL 使用的 get 方法passdef 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, Requestclass 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': 'liushuo@webscraping.com','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()
使用 url + 用户名 和 密码形式登录(使用 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 timeclass 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 = Noneself.__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.datadef 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)passdef 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 里面的数据。
使用 Cookies 模拟登录
From:https://www.jianshu.com/p/887af1ab4200
总结一下使用Cookie登录的好处:不需要知道登录url和表单字段以及其他参数,不需要了解登录的过程和细节。由于不是采用登录url, 用户名+密码的方式。配合工具使用,快速方便。
所谓用Cookie实现登录,就把过登录过的信息(包括用户名、密码以及其他的验证信息)打包一起发给服务器,告诉服务器我是登录验证过的。
不足之处,Cookie有过期时间,过一段时间再运行这个爬虫,需要重新获取一下Cookie的值。抓取数据过程是没有问题的。
关于Cookie的介绍:
-
Cookie分类
Cookie总是保存在用户客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie。Cookie的有效性,最短的浏览器关闭后就消失了,最长是可以一直保存,直到被删除。 -
Cookie用途
因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。
在典型的应用是网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么。
所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器中的状态。 -
Cookie的缺陷
1)Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
- 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题。(除非用HTTPS)
- Cookie的大小限制在4KB左右。对于复杂的存储需求来说是不够用的。