最近在弄scrapy框架的问题,感觉里面好玩的东西有很多,无意中在bilibili中看到关于在scrapy实现登录人人网的视频,人人网可能用户少,所以在现在的一些博客和教程里面看到最新的登录方法几乎没有,于是自己写了这篇博客。
进入正题,我们主要来说先下scrapy框架中的Request和Response对象,这两个对象贯穿scrapy框架。
Request请求网页对象,这个类需要传递一些参数,其中比较常用的参数如下所示:
url:request对象发送请求的链接。
callback:回调函数,即下载器下载完成后执行的回调函数。
method:请求方法,默认是get,如果是POST一般不用这个方法,使用FormRequest对象。
headers:请求头,对于一些固定的设置,放在setting.py中指定即可,对于非固定的,可以在发送请求时设置。
meta:可用于不同请求之间传送数据。
encoding:编码,默认utf-8。
dont_filter:表示不由调度器过滤,在执行多次请求的时候用的比较多。
errback:一般在出现错误的时候执行的函数。
Response对象一般是scrapy 自动构建,因此开发者不需要关心如何创建Response对象,Response主要属性如下:
url:Response的 url,一般与Request对象的url相同。
encoding:返回当前字符串编码和解码的格式。
body:将返回的数据作为bytes字符串返回。
xpath:利用XPath选择器提取数据。
css:利用CSS选择器提取数据。
text:Response解析的文本数据。
特别地,有时候我们需要在请求数据时候发送POST请求,我们可以利用Requuest子类FormRequest来实现,如果想要在爬虫一开始就发送POST请求,那么需要在爬虫类中重新start_requets()方法,且不再调用start_urls里面的url(也就是说不调用parse()方法)。
下面我们来分析人人网的登录界面,还是与上节登录豆瓣类似,打开登录页面,按F12调出开发者模式,勾选Persever log 在登录一栏输入正确的账号和密码,在XHR看到一个POST请求,如下图所示:
下面我们分析POST请求里面的formdata,如下图所示,通过我们多次试验,得到一个结论:即如果你输入的密码始终是同样的密码,那么它的动态加密的password在一定的时间内不会改变,所以我们在输入栏输入正确的密码的时候讲password里面的加密密码拿出来复制到代码中即可。这里面还有一些别的值一般不会改变,写代码直接复制粘贴。
这个POST请求的参数得到很好的解决,后面我们又遇到了一个问题,那就是发送POST请求的链接有时间戳问题,所以我们又要分析它的时间戳。例如http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2018801547691后面的2018801547691这一串数字所代表的的是什么意义,其实2018代表年,8表示时,01表示日,后面的54表示秒,691表示毫秒,这样分析之后,我们可以利用time库中一些方法来实现构造时间戳。
分析到这里,发送POST请求分析结束,然后,我们为了检测是否正确登录,我们打印出大鹏的主页,看是否能够正确保存(大鹏主页:http://www.renren.com/880151247/profile),(在人人网中,访问他人主页需要登录。)这里面主要涉及到Request和Response对象的调用问题。
下面简单说说scrapy框架使用
首先打开命令行窗口,进入E盘(我的项目放在这里面),然后利用scrpay startpoject renrnewang 命令行创建项目,继续输入命令行cd renrenwang进入renrenwang文件夹,创建爬虫类scrapy genspider renren renren.com,创建完成后,renrenwang文件夹中文件如下:
下图是注意的一些细节问题以及表单的传输。
在renren.py和setting.py中写上如下图源代码,在命令行输入scrapy crawl renren
在spider模块的renren.py里面
import scrapy
import time
class RenrenSpider(scrapy.Spider):
name = "renren"
#allowed_domains = ["'renren.com'"]
start_urls = ['http://www.renren.com/']
url='http://www.renren.com/'
def start_requests(self):
base_url='http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp='
s=time.strftime("%S")
ms=int(round(time.time()%(int(time.time())),3)*1000)
date_time='20188010'+str(s)+str(ms)
login_url=base_url+date_time
data={'email':'(账号)',
'icode':'',
'origURL':'http://www.renren.com/home',
'domain':'renren.com',
'key_id':'1',####注意这里面一定是字符型1,整型1会报错。如果使用
###request.session()应该没有这个问题
'captcha_type':'web_login',
'password':'(复制即可)',
'rkey':'fee3c0249fcf32f072eb0a4ccd82fa98',
'f':'https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DLwaiZlZgTeev7o9XOVRn3fvV4cWe7mW2wCUyYq73YZK%26wd%3D%26eqid%3D986b249200000e32000000035b8b47ec',
}
yield scrapy.FormRequest(url=login_url,formdata=data,callback=self.parse_login,dont_filter=True)
def parse_login(self,response):
yield scrapy.Request(url='http://www.renren.com/880151247/profile',callback=self.parse_text,dont_filter=True)
def parse_text(self,response):
with open(r'E:\renrenwang\renrenwang\大鹏.html','w',encoding='utf-8') as f:
f.write(response.text)
#在setting.py里面
# -*- coding: utf-8 -*-
# Scrapy settings for renrenwang project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'renrenwang'
SPIDER_MODULES = ['renrenwang.spiders']
NEWSPIDER_MODULE = 'renrenwang.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'renrenwang (+http://www.yourdomain.com)'
# Obey robots.txt rules
ROBOTSTXT_OBEY =False
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
#COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
' User-Agent':'Mozilla/5.0 '
}
最后我们打开大鹏.html文件,我们可以看到大鹏的主页,这样说明我们登陆成功。(如果点击一开始看到大鹏主页,然后立即退出需要登录,那不是程序登录失败,而是你的游览器没有登录,没有权限打开他人主页,将浏览器登录即可。)
其实,人人网如果同一个账号登录错误超过三次就会出现四个字的中文验证码,于是我们这种方法稳定性不高,在下一篇博客将会说到验证码破解问题,还是利用打码平台来破解验证码,然后将数据传输到POST请求中。 (目前我使用两种方法均可,不输入验证码利用上面的也能提交POST请求通过,可能人人网登陆本身设计有点欠缺。)
原创不易,如若转载,请注明作者和出处,谢谢。如有问题,欢迎留言交流