在利用scrapy框架爬各种网站时,一定会碰到某些网站是需要登录才能获取信息。
最近在学天善智能课堂韦玮老师的课程,python数据挖掘与分析实战 ,通过自己部分的代码和借鉴老师的项目,多次试验改进调试成功 豆瓣的模拟登录 ,顺便处理了怎么自动化的 处理验证码 。
我们大家都知道验证码的处理方式一般有几下三种:1.学习机器学习,处理图片识别
2.通过打码平台,接口处理。例如UU打码,快若打码等
3.半自动获取验证码,获取图片到本地,手动输入验证码再传过去登陆。
如下图所示,打开豆瓣登录首页,按F12键,我们可以看出在登陆时,需要输入的参数有哪些。将下面对应的相关参数,模拟浏览器,写入到程序中,便可以模拟登陆了。
实战操作
相关代码已经调试成功
目标网站: 豆瓣网,http://www.douban.com
实现:模拟登录豆瓣,验证码处理,登录到个人主页就算是success
数据:没有抓取数据,此实战主要是模拟登录和处理验证码的学习 。要是有需求要抓取数据,编写相关的抓取规则即可抓取内容。用xpath()表达式获取抓取地址。
注意:
1.豆瓣有反爬机制。所以要用伪装浏览器和用户代理"User-Agent",我用了"header"和start_request(),另外为了更好地处理验证码问题,我会把"cookie"保存起来,否则刷新了页面,就会丢失登录信息,所以保存登录状态。
2.豆瓣在登录成功后会自动跳转到首页,用"redir"来控制跳转后的页面。
3.实际发送表单时,用到FormRequest,所以要导入from scrapy.http import FormRequest,向服务器发送请求。
4.设置post表单数据,分有没有验证码,没有验证码时,只需要账号和密码就好。
我在这里贴出主要代码,spiders文件夹中db.py主要代码如下:
db.py
# -*- coding: utf-8 -*- import scrapy from scrapy.http import Request,FormRequest import urllib.request class DbSpider(scrapy.Spider): name = 'db' allowed_domains = ['douban.com'] #模拟浏览器 header={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"} '''start_urls = ('http://douban.com/',)''' #第一次爬使用方法 def start_requests(self): #url="https://accounts.douban.com/login" #url = "https://www.douban.com/accounts/login" # 豆瓣登录网址,post请求 return [Request(url="https://www.douban.com/accounts/login", callback=self.parse, headers=self.header, meta={"cookiejar":1})]#1:开启 def parse(self, response):#parse回调函数 url = "https://www.douban.com/accounts/login"#豆瓣登录网址,post请求 captcha=response.xpath("//img[@id='captcha_image']/@src").extract()#提取验证码 # 有无验证码弹出,判断链接长度是否大于0 if len(captcha)>0: print("此时有验证码") #人工输入验证码 localpath=r"C:\Users\Administrator\PycharmProjects\爬虫\douban\图片\captcha.png"#存放验证码 urllib.request.urlretrieve(captcha[0],filename=localpath) print("请查看本地验证码图片并输入验证码") captcha_value=input() #captcha_value =input('查看captcha.png,有验证码请输入:') # 验证码的值 data = { "form_email": "******", # 字典元素之间用逗号隔开 "form_password": "******", "captcha-solution": captcha_value, # 输入验证码的值 "redir": "https://www.douban.com/people/180905345/", # 登录之后跳转页,个人主页网 } else: print("此时没有验证码") data={ "form_email": "******",#字典元素之间用逗号隔开 "form_password":"******", "redir":"https://www.douban.com/people/180905345/",#登录之后跳转页,个人主页网址 } print("登陆中......")#FormRequest.from_response直接发送一项信息 return [FormRequest.from_response(response, meta={"cookiejar":response.meta["cookiejar"]}, headers=self.header, formdata=data, callback=self.next,#回调函数 dont_filter=True#start_requests中的url域名不能与allowed-domains不一致,否则会被过滤掉,添加dont_filter=True停用过滤功能 )] def next(self,response): print("此时已经登录完成,并爬取了个人中心的数据") title=response.xpath("/html/head/title/text()").extract() note=response.xpath("//div[@class='note']/text()").extract() print(title[0]) print(note[0])
我这里是用的半自动方式加载验证码,打码平台没有涉及到,有需要的同学可以用kuairuo打码,是一个比较好用的平台。希望可以给大家提供帮助。
我采用的是在pycharm编辑器中执行,并没有在cmd中执行scrapy自动爬虫:scrapy crawl (爬虫name名)。
因此需要在spider项目下添加main.py,启动scrapy程序。其代码如下:
main.py
from scrapy import cmdline
cmdline.execute("scrapy crawl db --nolog".split())
这里添加的--nolog的功能是,使不必要的细节不必展现出来,简化运行过程。最终运行结果成功登陆豆瓣网页,并跳转至个人主页。
笔记:
1.return Request的用法:
return [Request(url="https://www.douban.com/accounts/login",
callback=self.parse,
headers=self.header,
meta={"cookiejar":1})]#1:开启
2.打码平台的使用,直接利用验证码下载到本地,在手动输入验证码登陆3.FormRequest的用法:
return [FormRequest.from_response(response,
meta={"cookiejar":response.meta["cookiejar"]},
headers=self.header,
formdata=data,
callback=self.next,#回调函数
dont_filter=True#start_requests中的url域名不能与allowed-domains不一致,否则会被过滤掉,添加dont_filter=True停用过滤功能
)]
作者:ssqq
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章明显位置给出原文链接。
欢迎博友指出错误,我将改进,共同提高技术。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。