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 相关文章推荐
Python程序设计入门(4)模块和包
Jun 16 Python
python使用wmi模块获取windows下的系统信息 监控系统
Oct 27 Python
flask + pymysql操作Mysql数据库的实例
Nov 13 Python
Python3之读取连接过的网络并定位的方法
Apr 22 Python
python实现ID3决策树算法
Aug 29 Python
对python csv模块配置分隔符和引用符详解
Dec 12 Python
对DataFrame数据中的重复行,利用groupby累加合并的方法详解
Jan 30 Python
python的mysql数据库建立表与插入数据操作示例
Sep 30 Python
分享8点超级有用的Python编程建议(推荐)
Oct 13 Python
python读写文件write和flush的实现方式
Feb 21 Python
解决Python Matplotlib绘图数据点位置错乱问题
May 16 Python
python模块如何查看
Jun 16 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将数据导入到Foxmail
2006/10/09 PHP
PHP 遍历文件实现代码
2011/05/04 PHP
PHP中4种常用的抓取网络数据方法
2015/06/04 PHP
实例介绍PHP中zip_open()函数用法
2019/02/15 PHP
thinkphp5.1框架模板赋值与变量输出示例
2020/05/25 PHP
js 获取Listbox选择的值的代码
2010/04/15 Javascript
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
location.href用法总结(最主要的)
2013/12/27 Javascript
JavaScript中使用Object.create()创建对象介绍
2014/12/30 Javascript
JavaScript中的Truthy和Falsy介绍
2015/01/01 Javascript
Javascript中获取对象的原型对象的方法小结
2015/02/25 Javascript
在jQuery中处理XML数据的大致方法
2015/08/14 Javascript
纯javascript模仿微信打飞机小游戏
2015/08/20 Javascript
浅谈json取值(对象和数组)
2016/06/24 Javascript
用js实现简单算法的实例代码
2016/09/24 Javascript
AngularJS点击添加样式、点击变色设置的实例代码
2017/07/27 Javascript
详解nodejs通过代理(proxy)发送http请求(request)
2017/09/22 NodeJs
浅谈Node Inspector 代理实现
2017/10/19 Javascript
原生JS实现的碰撞检测功能示例
2018/05/18 Javascript
webpack优化的深入理解
2018/12/10 Javascript
JavaScript字符串处理常见操作方法小结
2019/11/15 Javascript
JavaScript 事件代理需要注意的地方
2020/09/08 Javascript
Python实现的数据结构与算法之链表详解
2015/04/22 Python
python中异常捕获方法详解
2017/03/03 Python
基于django channel实现websocket的聊天室的方法示例
2019/04/11 Python
Python除法之传统除法、Floor除法及真除法实例详解
2019/05/23 Python
Django后端分离 使用element-ui文件上传方式
2020/07/12 Python
CSS3+js实现简单的时钟特效
2015/03/18 HTML / CSS
公司应聘自荐书
2014/06/14 职场文书
幼儿园教师师德师风演讲稿:爱我所爱 无悔青春
2014/09/10 职场文书
2014国庆节演讲稿:祖国在我心中(400字)
2014/09/25 职场文书
2014年科普工作总结
2014/12/06 职场文书
2016年优秀党务工作者先进事迹材料
2016/02/29 职场文书
幼儿园教师教学反思
2016/03/02 职场文书
六年级作文之家庭作文
2019/12/12 职场文书
带你了解Java中的ForkJoin
2022/04/28 Java/Android