赵走x博客
首页
书籍
软件
工具
古诗词
搜索
登录
精通Scrapy爬虫:25、Scrapy模拟登录
精通Scrapy爬虫:24、登录实质
精通Scrapy爬虫:23、项目实战:下载360图片
精通Scrapy爬虫:22、项目实战:爬取matplotlib例子源码文件
精通Scrapy爬虫:21、下载文件和图片:FilesPipeline和ImagesPipeline
精通Scrapy爬虫:20、项目练习
精通Scrapy爬虫:16、使用LinkExtractor提取链接
精通Scrapy爬虫:19、Exporter添加导出数据格式
精通Scrapy爬虫:18、使用Exporter导出数据
精通Scrapy爬虫:17、LinkExtractor描述提取规则
精通Scrapy爬虫:15、将数据存入MongoDB
精通Scrapy爬虫:14、过滤重复数据
精通Scrapy爬虫:13、Item Pipeline
精通Scrapy爬虫:12、Field元数据
精通Scrapy爬虫:11、Item和Field
精通Scrapy爬虫:10、CSS选择器
精通Scrapy爬虫:9、XPath
精通Scrapy爬虫:8、Response内置Selector
精通Scrapy爬虫:7、Selector对象
精通Scrapy爬虫:6、Spider开发流程
精通Scrapy爬虫:5、Request和Response对象
精通Scrapy爬虫:4、Scrapy框架结构及工作原理
精通Scrapy爬虫:3、编写第一个Scrapy爬虫
精通Scrapy爬虫:2、Scrapy简介及安装
精通Scrapy爬虫:1、网络爬虫是什么
精通Scrapy爬虫:25、Scrapy模拟登录
资源编号:75973
精通Scrapy
爬虫
热度:27
现在大家了解了登录的实质,其核心是向服务器发送含有登录表单数据的HTTP请求(通常是POST)。Scrapy提供了一个FormRequest类(Request的子类),专门用于构造含有表单数据的请求,FormRequest的构造器方法有一个formdata参数,接收字典形式的表单数据。
# 1、使用FormRequest 现在大家了解了登录的实质,其核心是向服务器发送含有登录表单数据的HTTP请求(通常是POST)。Scrapy提供了一个FormRequest类(Request的子类),专门用于构造含有表单数据的请求,FormRequest的构造器方法有一个formdata参数,接收字典形式的表单数据。接下来,我们在scrapy shell环境下演示如何使用FormRequest模拟登录。 首先爬取登录页面http://example.webscraping.com/user/login : ``` $ scrapy shell http://example.webscraping.com/user/login ``` 通过之前的分析,我们已经了解了表单数据应包含的信息:账号和密码信息,再加3个隐藏
中的信息。先把这些信息收集到一个字典中,然后使用这个表单数据字典构造FormRequest对象: ``` >>> # 先提取3 个隐藏
中包含的信息,它们在
中 >>> sel = response.xpath('//div[@style]/input') >>> sel [
,
,
] >>> # 构造表单数据字典 >>> fd = dict(zip(sel.xpath('./@name').extract(), sel.xpath('./@value').extract())) >>> fd {'_formkey': '432dcb0c-0d85-443f-bb50-9644cfeb2f2b', '_formname': 'login', '_next': '/'} >>> # 填写账号和密码信息 >>> fd['email'] = 'liushuo@webscraping.com' >>> fd['password'] = '12345678' >>> fd {'_formkey': '432dcb0c-0d85-443f-bb50-9644cfeb2f2b', '_formname': 'login', '_next': '/', 'email': 'liushuo@webscraping.com', 'password': '12345678'} >>> from scrapy.http import FormRequest >>> request = FormRequest('http://example.webscraping.com/user/login', formdata=fd) ``` 以上是直接构造FormRequest对象的方式,除此之外还有一种更为简单的方式,即调用FormRequest的from_response方法。调用时需传入一个Response对象作为第一个参数,该方法会解析Response对象所包含页面中的
元素,帮助用户创建FormRequest对象,并将隐藏
中的信息自动填入表单数据。使用这种方式,我们只需通过formdata参数填写账号和密码即可,代码如下: >>> fd = {'email': 'liushuo@webscraping.com', 'password': '12345678'} >>> request = FormRequest.from_response(response, formdata=fd) 使用任意方式构造好FormRequest对象后,接下来提交表单请求: >>> fetch(request) [scrapy] DEBUG: Redirecting (303) to
from
[scrapy] DEBUG: Crawled (200)
(referer: None) 在log信息中,可以看到和浏览器提交表单时类似的情形:POST请求的响应状态码为303,之后Scrapy自动再发送一个GET请求下载跳转页面。此时,可以通过在页面中查找特殊字符串或在浏览器中查看页面验证登录是否成功,如图10-7所示。 >>> 'Welcome Liu' in response.text True >>> view(response) 图10-7 验证结果表明模拟登录成功了。显然,Scrapy发送的第2个GET请求携带了第1个POST请求获取的Cookie信息,为请求附加Cookie信息的工作是由Scrapy内置的下载中间件CookiesMiddleware自动完成的。现在,我们可以继续发送请求,爬取那些只有登录后才能获取的信息了,这里以爬取用户个人信息为例,如图10-8所示。 >>> fetch('http://example.webscraping.com/user/profile') #下载用户个人信息页面 [scrapy] DEBUG: Crawled (200)
>>> view(response) 图10-8 提取页面中的用户个人信息,代码如下: >>> keys = response.css('table label::text').re('(.+):') >>> keys ['First name', 'Last name', 'E-mail'] >>> values = response.css('table td.w2p_fw::text').extract() >>> values ['Liu', 'Shuo', 'liushuo@webscraping.com'] >>> dict(zip(keys, values)) {'E-mail': 'liushuo@webscraping.com', 'First name': 'Liu', 'Last name': 'Shuo'} 到此,使用FormRequest模拟登录的过程就演示完了。 10.2.2 实现登录Spider 整理10.2.1小节中登录http://example.webscraping.com后爬取用户个人信息的代码,实现一个LoginSpider,代码如下: # -*- coding: utf-8 -*- import scrapy from scrapy.http import Request, FormRequest class LoginSpider(scrapy.Spider): name = "login" allowed_domains = ["example.webscraping.com"] start_urls = ['http://example.webscraping.com/user/profile'] def parse(self, response): # 解析登录后下载的页面,此例中为用户个人信息页面 keys = response.css('table label::text').re('(.+):') values = response.css('table td.w2p_fw::text').extract() yield dict(zip(keys, values)) # ----------------------------登录--------------------------------- # 登录页面的url login_url = 'http://example.webscraping.com/user/login' def start_requests(self): yield Request(self.login_url, callback=self.login) def login(self, response): # 登录页面的解析函数,构造FormRequest对象提交表单 fd = {'email': 'liushuo@webscraping.com', 'password': '12345678'} yield FormRequest.from_response(response, formdata=fd, callback=self.parse_login) def parse_login(self, response): # 登录成功后,继续爬取start_urls 中的页面 if 'Welcome Liu' in response.text: yield from super().start_requests() # Python 3语法 解释上述代码如下: ● 覆写基类的start_requests方法,最先请求登录页面。 ● login方法为登录页面的解析函数,在该方法中进行模拟登录,构造表单请求并提交。 ● parse_login方法为表单请求的响应处理函数,在该方法中通过在页面查找特殊字符串'Welcome Liu'判断是否登录成功,如果成功,调用基类的start_requests方法,继续爬取start_urls中的页面。 我们这样设计LoginSpider就是想把模拟登录和爬取内容的代码分离开,使得逻辑上更加清晰。