python编程快速上手(持续更新中…)
python爬虫从入门到精通
Scrapy爬虫框架
文章目录
1. 回顾之前的模拟登陆的方法
1.1 requests模块是如何实现模拟登陆的?
直接携带cookies请求页面
找url地址,发送post请求存储cookie
1.2 selenium是如何模拟登陆的?
找到对应的input标签,输入文本点击登陆
1.3 scrapy的模拟登陆
1.直接携带cookies
2.找url地址,发送post请求存储cookie
3. scrapy携带cookies直接获取需要登陆后的页面
2.应用场景
cookie过期时间很长,常见于一些不规范的网站
能在cookie过期之前把所有的数据拿到
配合其他程序使用,比如其使用selenium把登陆之后的cookie获取到保存到本地,scrapy发送请求之前先读取本地cookie
2.1 实现:重构scrapy的start_requests方法
scrapy中start_url是通过start_requests来进行处理的,其实现代码如下
# 这是源代码
def start_requests(self):
cls = self.__class__
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 (see %s.%s)." % (
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)
所以对应的,如果start_url地址中的url是需要登录后才能访问的url地址,则需要重写start_request方法并在其中手动添加上cookie
2.2 携带cookies登陆gitee
import scrapy
class Git1Spider(scrapy.Spider):
name = 'git1'
allowed_domains = ['gitee.com']
start_urls = ['https://gitee.com/ZHOUDOUJUN']
def start_requests(self):
url = self.start_urls[0]
temp = '1111111111user_locale=zh-CN; oschina_new_user=false'
cookies = {data.split('=')[0]:data.split('=')[-1]for data in temp.split('; ')}
yield scrapy.Request(
url=url,
callback=self.parse,
cookies=cookies
)
def parse(self, response):
with open("git_with_cookies.html", "w")as f:
f.write(response.text)
注意:
scrapy中cookie不能够放在headers中,在构造请求的时候有专门的cookies参数,能够接受字典形式的coookie
在setting中设置ROBOTS协议、USER_AGENT
3. scrapy.Request发送post请求
我们知道可以通过scrapy.Request()指定method、body参数来发送post请求;但是通常使用scrapy.FormRequest()来发送post请求
3.1 发送post请求
注意:scrapy.FormRequest()能够发送表单和ajax请求,参考阅读 https://www.jb51.net/article/146769.htm
3.1.1 思路分析
找到post的url地址:点击登录按钮进行抓包,然后定位url地址为https://github.com/session
找到请求体的规律:分析post请求的请求体,其中包含的参数均在前一次的响应中
否登录成功:通过请求个人主页,观察是否包含用户名
3.1.2 代码实现如下:
import scrapy
class Git2Spider(scrapy.Spider):
name = 'git2'
allowed_domains = ['gitee.com']
start_urls = ['https://gitee.com/login']
def parse(self, response):
authenticity_token = response.xpath('//input[@name="authenticity_token"]/@value').extract_first()
# 构造post数据
post_data = {
'encrypt_key': 'password',
'utf8': '✓',
'authenticity_token': authenticity_token,
'redirect_to_url': '',
'user[login]': '1538352223@qq.com',
'encrypt_data[user[password]]': '11111111114AoUK8Hep75V/jCzHNGNuBEHZ1a59n5sYdWo4v4=',
'user[remember_me]': '0'
}
print(post_data)
# 构造一个post请求对象
yield scrapy.FormRequest(
url='https://gitee.com/login',
callback=self.login,
formdata=post_data
)
def login(self, response):
yield scrapy.Request(
url='https://gitee.com/profile/account_information',
callback=self.check_login
)
def check_login(self, response):
with open("git_with_post.html", "w")as f:
f.write(response.text)
小技巧
在settings.py中通过设置COOKIES_DEBUG=TRUE 能够在终端看到cookie的传递传递过程