python爬虫之自动登录与验证码识别


Posted in Python onJune 15, 2020

在用爬虫爬取网站数据时,有些站点的一些关键数据的获取需要使用账号登录,这里可以使用requests发送登录请求,并用Session对象来自动处理相关Cookie。

另外在登录时,有些网站有时会要求输入验证码,比较简单的验证码可以直接用pytesser来识别,复杂的验证码可以依据相应的特征自己采集数据训练分类器。

以CSDN网站的登录为例,这里用Python的requests库与pytesser库写了一个登录函数。如果需要输入验证码,函数会首先下载验证码到本地,然后用pytesser识别验证码后登录,对于CSDN登录验证码,pytesser的识别率很高。

其中的pytesser的下载地址为: pytesser下载

具体代码如下:

#coding:utf-8
import sys
import time
import urllib
import shutil
import pytesser
import requests

from lxml import etree

config = {'gid': 1}

def parse(s, html, idx):
 result = {}

 tree = etree.HTML(html)
 try:
 result['lt'] = tree.xpath('//input[@name="lt"]/@value')[0]
 result['execution'] = tree.xpath('//input[@name="execution"]/@value')[0]
 result['path'] = tree.xpath('//form[@id="fm1"]/@action')[0]
 except IndexError, e:
 return None

 valimg = None
 valimgs = tree.xpath('//img[@id="yanzheng"]/@src')
 if len(valimgs) > 0:
 valimg = valimgs[0]

 validateCode = None
 if valimg:
 fname = 'img/' + str(idx) + '_' + str(config['gid']) + '.jpg'
 config['gid'] = config['gid'] + 1
 ri = s.get("https://passport.csdn.net" + valimg)
 with open(fname, 'wb') as f:
  for chk in ri:
  f.write(chk)
  f.close()
 validateCode = pytesser.image_file_to_string(fname)
 validateCode = validateCode.strip()
 validateCode = validateCode.replace(' ', '')
 validateCode = validateCode.replace('\n', '')
 result['validateCode'] = validateCode

 return result

def login(usr, pwd, idx):
 s = requests.Session()

 r = s.get('https://passport.csdn.net/account/login',
 headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Host': 'passport.csdn.net', })

 while True:
 res = parse(s, r.text, idx)
 if res == None:
  return False
 url = 'https://passport.csdn.net' + res['path']
 form = {'username': usr, 'password':pwd, '_eventId':'submit', 'execution':res['execution'], 'lt':res['lt'],}
 if res.has_key('validateCode'):
  form['validateCode'] = res['validateCode']
 s.headers.update({
  'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0',
  'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4',
  'Content-Type': 'application/x-www-form-urlencoded',
  'Host': 'passport.csdn.net',
  'Origin': 'https://passport.csdn.net',
  'Referer': 'https://passport.csdn.net/account/login',
  'Upgrade-Insecure-Requests': 1,
  })
 r = s.post(url, data=form)

 tree = etree.HTML(r.text)
 err_strs = tree.xpath('//span[@id="error-message"]/text()')
 if len(err_strs) == 0:
  return True
 err_str = err_strs[0]
 print err_str
 err = err_str.encode('utf8')

 validate_code_err = '验证码错误'
 usr_pass_err = '帐户名或登录密码不正确,请重新输入'
 try_later_err = '登录失败连续超过5次,请10分钟后再试'

 if err[:5] == validate_code_err[:5]:
  pass
 elif err[:5] == usr_pass_err[:5]:
  return False
 elif err[:5] == try_later_err[:5]:
  return False
 else:
  return True

if __name__ == '__main__':
 main(sys.argv[1], sys.argv[2], 0)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
django自定义Field实现一个字段存储以逗号分隔的字符串
Apr 27 Python
python实现获取序列中最小的几个元素
Sep 25 Python
Python MySQLdb Linux下安装笔记
May 09 Python
Python提取Linux内核源代码的目录结构实现方法
Jun 24 Python
Python爬取网易云音乐上评论火爆的歌曲
Jan 19 Python
python3.4用循环往mysql5.7中写数据并输出的实现方法
Jun 20 Python
Python机器学习logistic回归代码解析
Jan 17 Python
python通过配置文件共享全局变量的实例
Jan 11 Python
PyQt5 实现给窗口设置背景图片的方法
Jun 13 Python
Django对models里的objects的使用详解
Aug 17 Python
Django利用elasticsearch(搜索引擎)实现搜索功能
Nov 26 Python
8g内存用python读取10文件_面试题-python 如何读取一个大于 10G 的txt文件?
May 28 Python
python使用matplotlib模块绘制多条折线图、散点图
Apr 26 #Python
python绘制多个曲线的折线图
Mar 23 #Python
python使用Matplotlib绘制分段函数
Sep 25 #Python
python使用Matplotlib画饼图
Sep 25 #Python
python使用Matplotlib画条形图
Mar 25 #Python
python使用matplotlib画饼状图
Sep 25 #Python
符合语言习惯的 Python 优雅编程技巧【推荐】
Sep 25 #Python
You might like
关于在php.ini中添加extension=php_mysqli.dll指令的说明
2007/06/14 PHP
php adodb介绍
2009/03/19 PHP
微信支付的开发流程详解
2016/09/13 PHP
Yii框架扩展CGridView增加导出CSV功能的方法
2017/05/24 PHP
Laravel使用原生sql语句并调用的方法
2019/10/09 PHP
laravel实现上传图片并在页面显示的例子
2019/10/14 PHP
php使用Swoole实现毫秒级定时任务的方法
2020/09/04 PHP
一个符号插入器 中用到的js代码
2007/09/04 Javascript
从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件
2011/02/23 Javascript
基于jquery实现无限级树形菜单
2016/03/22 Javascript
JavaScript实现清空(重置)文件类型INPUT元素值的方法
2016/11/17 Javascript
Js自动截取字符串长度,添加省略号(……)的实现方法
2017/03/06 Javascript
jquery仿京东商品放大浏览页面
2017/06/06 jQuery
jQuery除指定区域外点击任何地方隐藏DIV功能
2017/11/13 jQuery
微信小程序数字滚动插件使用详解
2018/02/02 Javascript
Vue2.5通过json文件读取数据的方法
2018/02/27 Javascript
JS编写兼容IE6,7,8浏览器无缝自动轮播
2018/10/12 Javascript
Vue.js 时间转换代码及时间戳转时间字符串
2018/10/16 Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
2020/11/02 Javascript
如何在vue中使用百度地图添加自定义覆盖物(水波纹)
2020/11/03 Javascript
详解js创建对象的几种方式和对象方法
2021/03/01 Javascript
python简单实现基数排序算法
2015/05/16 Python
Django项目中model的数据处理以及页面交互方法
2018/05/30 Python
python中的print()输出
2019/04/12 Python
Python 占位符的使用方法详解
2019/07/10 Python
Python全局锁中如何合理运用多线程(多进程)
2019/11/06 Python
python redis 批量设置过期key过程解析
2019/11/26 Python
在CentOS7下安装Python3教程解析
2020/07/09 Python
Python如何实现大型数组运算(使用NumPy)
2020/07/24 Python
Html5监听手机摇一摇事件的实现
2019/11/07 HTML / CSS
建筑工地宣传标语
2014/06/18 职场文书
大学生求职简历自我评价
2015/03/02 职场文书
MySQL 隔离数据列和前缀索引的使用总结
2021/05/14 MySQL
用python实现监控视频人数统计
2021/05/21 Python
Python关于OS文件目录处理的实例分享
2021/05/23 Python
Python写情书? 10行代码展示如何把情书写在她的照片里
2022/04/21 Python