每日分享:
有人三分钟泡面,有人三小时煲汤;有人的外卖已送达,而有人才刚切好菜。当你选好了你要的方式,坚定下去,别胡思乱想;我们要走的路不一样,花期也不一样,不必焦虑。
目标:
- 应用 请求对象cookies参数的使用
- 了解 start_requests函数的作用
- 应用 构造并发送post请求
一、回顾之前的模拟登录方法
1.1 requests模块如何实现模拟登录
- 直接携带cookies请求页面
- 找url地址,发送post请求存储cookie
1.2 selenium如何模拟登录
- 找到对应的input标签,输入文本(账号密码)点击登录
1.3 scrapy模拟登录(和requests登录思想一致)
- 直接携带cookies
- 找url地址,发送post请求存储cookie
二、scrapy携带cookies直接获取需要登录后的页面
应用场景:
- cookie过期时间很长,常用于一些比较low的网站(对cookie的管理不严)
- 能在cookie过期之前把所有的数据拿到
- 配合其他程序使用,比如其使用selenium把登录之后的cookie获取保存到本地,scrapy发送请求之前先读取本地cookie
2.1 实现:重构scrapy中的start_requests方法
scrapy中的start_url是通过start_requests来进行处理的,其实现代码如下:
#源代码 def start_requests(self): cls = self.__class__ if not self.start_urls and hasattr(self, 'start_url'): raise AttributeError( "Crawling could not start: 'start_urls' not found " "or empty (but found 'start_url' attribute instead, " "did you miss an 's'?)") if method_is_overridden(cls, Spider, 'make_requests_from_url'): warnings.warn( "Spider.make_requests_from_url method is deprecated; it " "won't be called in future Scrapy releases. Please " "override Spider.start_requests method instead " f"(see {cls.__module__}.{cls.__name__}).", ) for url in self.start_urls: yield self.make_requests_from_url(url) else: for url in self.start_urls: yield Request(url, dont_filter=True) def make_requests_from_url(self, url): """ This method is deprecated. """ warnings.warn( "Spider.make_requests_from_url method is deprecated: " "it will be removed and not be called by the default " "Spider.start_requests method in future Scrapy releases. " "Please override Spider.start_requests method instead." ) return Request(url, dont_filter=True)
所以说,如果start_url地址中的url是需要登录后才能访问的url地址,则需要重写start_request方法并在其中手动添加上cookie
2.2 携带cookies登录github
提示:
cookie要用昵称密码登录,而且最好是没有用验证码,直接登录进去的,之后抓包获取cookie;需要验证码抓包获取的cookie会登录失败
import scrapy class CgithubSpider(scrapy.Spider): name = 'cgithub' allowed_domains = ['github.com'] start_urls = ['https://github.com/aoospdk'] # 重构start_requests方法 def start_requests(self): # 抓包获取的cookie_str cookie_str = '登录后抓包获取的cookie' # 将cookie_str转化为cookie_dict cookie_dict = {data.split('=')[0]: data.split('=')[1] for data in cookie_str.split('; ')} yield scrapy.Request( url=self.start_urls[0], callback=self.parse, cookies=cookie_dict ) # 输出title,后面没有· GitHub就证明登录成功 def parse(self, response): print('--------------', response.xpath('/html/head/title/text()').extract_first())
注意:
- scrapy中cookie不能够放在headers中,在构造请求的时候有专门的cookies参数,能够接收字典形式的cookie
- 要在setting中注释ROBOTS协议,并且打开注释USER_AGENT(要把内容替换为自己的user-agent)
结果:
可以看到,输出后面没有· GitHub,证明登录成功
三、scrapy.Request发送post请求
可以通过scrapy.Request()指定method、body参数来发送post请求;但通常使用scrapy.FormRequest()来发送post请求
- 找到post的url地址:抓包获取
- 找到请求体规律:分析post请求中的数据,构建post_data
- 判断是否登录成功:看title
代码框架如下:
import scrapy class Cgithub2Spider(scrapy.Spider): name = 'cgithub2' allowed_domains = ['github.com'] start_urls = ['https://github.com/session'] def parse(self, response): # 登录页面解析出post数据 post_data = { "" } # 使用FormRequest发送post请求 yield scrapy.FormRequest( url='https://github.com/session', callback=self.after_login, formdata=post_data ) # 发送get请求 def after_login(self): yield scrapy.Request(url='https://github.com/aoospdk', callback=self.cheak_login) # 输出title def cheak_login(self, response): print('--------------', response.xpath('/html/head/title/text()').extract_first())
可以在settings.py中通过设置COOKIES_DEBUG=true 能够在终端看到cookie的传递过程
总结:
- start_urls中的url地址是交给start_requests处理的,如果有必要,可以重写start_request函数
- 直接携带cookie登录:cookie只能传递给cookies参数接收
- scrapy.FormRequest()发送post请求
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试