在之前关于urllib的文章中,简单使用了模拟登录。过程是先使用POST登录获得登陆之后的信息,然后带着cookie信息访问其他页面,就可以跳过登录验证。在python原生的类库中可以使用这种方式。在scrapy中也封装了关于模拟登录的类库,这节就研究如何使用它。
第一种方式:暴力但是有效
直接在网页上登录,然后通过chrome浏览器的开发者工具,查找cookie的值,然后复制到代码中,之后的每一次请求都使用这个cookie值。使用人人网测试一下,首先在浏览器中登录一下,然后找到cookie值。
cookie值
然后把cookie复制下来,用字典存放。
class Login1Spider(scrapy.Spider): name = 'login1' allowed_domains = ['www.renren.com'] start_urls = ['http://www.renren.com/'] cookies = {...} #里面是登录之后的cookie值 #重写start_requests()方法,此时不会直接爬取start_urls中的链接,也不会运行parse()方法,需要重新指定页面解析的parse方法 def start_requests(self): for url in self.start_urls: yield scrapy.FormRequest(url, cookies=self.cookies, callback=self.parse_page) def parse_page(self, response): with open("login1.html", "w", encoding='utf8') as f: f.write(response.body.decode("utf-8"))
运行爬虫,在项目中生成了login1.html,打开看一下<title>标签,可以看到是登录之后的个人主页。
第二种方式:适用于POST请求
模拟登录的行为,发送post请求,需要填入所有的表单数据。
class Login2Spider(scrapy.Spider): name = 'login2' allowed_domains = ['www.renren.com'] start_urls = [] def start_requests(self): url = 'http://www.renren.com/PLogin.do' yield scrapy.FormRequest( url=url, formdata={"email": "用户名", "password": "密码"}, callback=self.parse_page) def parse_page(self, response): with open("login2.html", "w", encoding='utf8') as f: f.write(response.body.decode("utf-8"))
运行爬虫,在项目中生成了login2.html,打开看一下<title>标签,可以看到是登录之后的个人主页。
第三种方式:Post请求的升级版
很多post请求里面除了用户名和密码,还有一些其他的比如token等数据,每一次都是不同的。此时使用手动填入post数据就很麻烦了。解决办法:首先发送登录页面的get请求,获取到页面里的登录必须的参数,然后再发送POST请求进行登录。
class Login3Spider(scrapy.Spider): name = 'login3' allowed_domains = ['www.renren.com'] start_urls = ['http://www.renren.com/PLogin.do'] def parse(self, response): yield scrapy.FormRequest.from_response( response, formdata={"email": "用户名", "password": "密码"}, callback=self.parse_page ) def parse_page(self, response): print(response.url) url = "http://www.renren.com/880151247/profile" # 大鹏的人人主页 yield scrapy.Request(url, callback=self.parse_newpage) def parse_newpage(self, response): print(response.body.decode("utf-8")) with open("login3.html", "w", encoding='utf8') as f: f.write(response.body.decode("utf-8"))
运行爬虫,控制台上输出了登陆者个人主页,并且在项目中生成了login3.html,打开看一下<title>标签,可以看到是需要跳转的页面。
完整代码