一 . 模拟登陆案例(识别验证码)

 1 . 打码平台 - 云打码 : www.yundama.com 

  使用步骤 :

    - 注册两个账户,普通用户和开发者用户 :

    - 登陆

      普通用户查看余额

      登陆开发者用户 :

        创建一个软件: 我的软件 -> 创建软件

        下载示例代码: 开发者中心 -> 下载最新云打码DLL -> PythonHTTP示例下载

    - 下载后解压缩,如下 :

                              

import http.client, mimetypes, urllib, json, time, requests

######################################################################

class YDMHttp:

    apiurl = 'http://api.yundama.com/api.php'
username = ''
password = ''
appid = ''
appkey = '' def __init__(self, username, password, appid, appkey):
self.username = username
self.password = password
self.appid = str(appid)
self.appkey = appkey def request(self, fields, files=[]):
response = self.post_url(self.apiurl, fields, files)
response = json.loads(response)
return response def balance(self):
data = {'method': 'balance', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey}
response = self.request(data)
if (response):
if (response['ret'] and response['ret'] < 0):
return response['ret']
else:
return response['balance']
else:
return -9001 def login(self):
data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey}
response = self.request(data)
if (response):
if (response['ret'] and response['ret'] < 0):
return response['ret']
else:
return response['uid']
else:
return -9001 def upload(self, filename, codetype, timeout):
data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'codetype': str(codetype), 'timeout': str(timeout)}
file = {'file': filename}
response = self.request(data, file)
if (response):
if (response['ret'] and response['ret'] < 0):
return response['ret']
else:
return response['cid']
else:
return -9001 def result(self, cid):
data = {'method': 'result', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'cid': str(cid)}
response = self.request(data)
return response and response['text'] or '' def decode(self, filename, codetype, timeout):
cid = self.upload(filename, codetype, timeout)
if (cid > 0):
for i in range(0, timeout):
result = self.result(cid)
if (result != ''):
return cid, result
else:
time.sleep(1)
return -3003, ''
else:
return cid, '' def report(self, cid):
data = {'method': 'report', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'cid': str(cid), 'flag': ''}
response = self.request(data)
if (response):
return response['ret']
else:
return -9001 def post_url(self, url, fields, files=[]):
for key in files:
files[key] = open(files[key], 'rb');
res = requests.post(url, files=files, data=fields)
return res.text ###################################################################### # 用户名
username = 'username' # 密码
password = 'password' # 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
appid = 1 # 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
appkey = '22cc5376925e9387a23cf797cb9ba745' # 图片文件
filename = 'getimage.jpg' # 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
codetype = 1004 # 超时时间,秒
timeout = 60 # 检查
if (username == 'username'):
print('请设置好相关参数再测试')
else:
# 初始化
yundama = YDMHttp(username, password, appid, appkey) # 登陆云打码
uid = yundama.login();
print('uid: %s' % uid) # 查询余额
balance = yundama.balance();
print('balance: %s' % balance) # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
cid, result = yundama.decode(filename, codetype, timeout);
print('cid: %s, result: %s' % (cid, result)) #######################################

YDMHTTPDemo3.x.py 内容

 2 . 案例一 : 模拟登陆 人人网,爬取个人中心页面的数据 

# 获取验证码的图片识别

import http.client, mimetypes, urllib, json, time, requests

######################################################################

class YDMHttp:

    apiurl = 'http://api.yundama.com/api.php'
username = ''
password = ''
appid = ''
appkey = '' def __init__(self, username, password, appid, appkey):
self.username = username
self.password = password
self.appid = str(appid)
self.appkey = appkey def request(self, fields, files=[]):
response = self.post_url(self.apiurl, fields, files)
response = json.loads(response)
return response def balance(self):
data = {'method': 'balance', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey}
response = self.request(data)
if (response):
if (response['ret'] and response['ret'] < 0):
return response['ret']
else:
return response['balance']
else:
return -9001 def login(self):
data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey}
response = self.request(data)
if (response):
if (response['ret'] and response['ret'] < 0):
return response['ret']
else:
return response['uid']
else:
return -9001 def upload(self, filename, codetype, timeout):
data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'codetype': str(codetype), 'timeout': str(timeout)}
file = {'file': filename}
response = self.request(data, file)
if (response):
if (response['ret'] and response['ret'] < 0):
return response['ret']
else:
return response['cid']
else:
return -9001 def result(self, cid):
data = {'method': 'result', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'cid': str(cid)}
response = self.request(data)
return response and response['text'] or '' def decode(self, filename, codetype, timeout):
cid = self.upload(filename, codetype, timeout)
if (cid > 0):
for i in range(0, timeout):
result = self.result(cid)
if (result != ''):
return cid, result
else:
time.sleep(1)
return -3003, ''
else:
return cid, '' def report(self, cid):
data = {'method': 'report', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'cid': str(cid), 'flag': ''}
response = self.request(data)
if (response):
return response['ret']
else:
return -9001 def post_url(self, url, fields, files=[]):
for key in files:
files[key] = open(files[key], 'rb');
res = requests.post(url, files=files, data=fields)
return res.text
######################################################################
# 用户调用这个函数,这个函数在调用上面的函数,进行图片的识别 def getCodeData(username, pwd, codePath, codeType):
username = username # 用户名(云打码普通用户用户名)
password = pwd # 普通用户对应的密码
appid = 6003 # 软件代码,开发者分成必要参数。登录开发者后台【我的软件】获得!
appkey = '1f4b564483ae5c907a1d34f8e2f2776c' # 通讯密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
filename = codePath # 识别的图片的路径
codetype = codeType # 识别的类型,在帮助文档可查看对应验证码类型
timeout = 20
if (username == 'username'):
print('请设置好相关参数再测试')
else:
# 初始化
yundama = YDMHttp(username, password, appid, appkey) # 登陆云打码
uid = yundama.login();
# print('uid: %s' % uid) # 查询余额
balance = yundama.balance();
# print('balance: %s' % balance) # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
cid, result = yundama.decode(filename, codetype, timeout);
# print('cid: %s, result: %s' % (cid, result)) return result

getCodeData函数

# 人人网的模拟登陆
import requests
import urllib
from lxml import etree
# 获取session对象
session = requests.Session() # 下载验证码图片
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
url = 'http://www.renren.com'
page_text = requests.get(url=url, headers=headers).text tree = etree.HTML(page_text)
# 获取验证码的图片地址
code_img_url = tree.xpath('//*[@id="verifyPic_login"]/@src')[0]
# 将验证码的地址url保存到本地,然后调用云打码
urllib.request.urlretrieve(url=code_img_url, filename='code.jpg') # 识别验证码图片中的数据值,2004表示4位纯汉字,其他类型代码参考云打码帮助文档
code_data = getCodeData(云打码用户名', '云打码密码', './code.jpg', 2004)
# print(code_data) # code_data为识别结果
# 模拟浏览器登录 ,登录的url
login_url = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2019141727367'
data = {
"email":"1547360919@qq.com",
"icode":code_data,
"origURL":"http://www.renren.com/home",
"domain":"renren.com",
"key_id":"",
"captcha_type":"web_login",
"password":"38ce96b6b81595f845e55c1dd4e712ad6f1efe50fe31dbd5bf517b273d7c3b6e",
"rkey":"07a9f1810ecf9b507634a45447a628e7",
"f":""
} # 如果请求成功,产生的cookie会自动保存在session对象中
# 使用session进行post请求发送,防止cookie是动态,cookie保存到session对象中
# 可以进行免密登录,
session.post(url=login_url, data=data, headers=headers)
# 登录人人网的主页
url = 'http://www.renren.com/448850039/profile'
page_text = session.get(url=url, headers=headers).text with open('renren.html', 'w', encoding='utf8') as f:
f.write(page_text)

3 . 案例二 : 模拟登录古诗文网 

# 模拟登陆古诗文网
from lxml import etree
import requests s = requests.Session() headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
} login_url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
page_text = requests.get(url=login_url, headers=headers, verify=False).text
# verify=False是解决请求https协议问题,SSL错误 tree = etree.HTML(page_text)
img_code_url = 'https://so.gushiwen.org' + tree.xpath('//*[@id="imgCode"]/@src')[0] # 验证码图片请求也会有session产生,因此不能使用urllib的urlretrieve方法
img_data = s.get(url=img_code_url, headers=headers, verify=False).content
with open('./gs_code_img.jpg','wb') as f:
f.write(img_data) # 识别验证码
code_data = getCodeData('bobo328410948', 'bobo328410948', './gs_code_img.jpg', 1004) relogin_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
# 当有些参数是动态变化的时,我们可以去网页源代码中找找
data = {
"__VIEWSTATE":"u+DzAnizDr8zKG7K/Q/OHyl4Kae1i0R5uxnuMk+EONOCJb5GTyGoJgnx1n/wlOx4XePU+CN5dRcmV/ptirBjyW6SyzcQqdOMuyeIbuFfEWNcUm7K00I9RH7g5gA=",
"__VIEWSTATEGENERATOR":"C93BE1AE",
"from":"http://so.gushiwen.org/user/collect.aspx",
"email":"1547360919@qq.com",
"pwd":"512abc...",
"code":code_data,
"denglu":"登录"
}
page_data = s.post(url=relogin_url, data=data, headers=headers, verify=False).text
with open('./gushici.html', 'w', encoding='utf8') as f:
f.write(page_data)

 4 . 随机获取User-Agent 

# 但是因其服务器不稳定,有时候获取不到,因此我们很少用
from fake_useragent import UserAgent
ua = UserAgent(verify_ssl=False,use_cache_server=False).random
headers = {
'User-Agent':ua
} # fake_useragent的安装方式为 pip install fake-useragent

二 . selenium

   selenium是一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化操作。可用于获取动态加载的数据。

 1 . 环境搭建 

  - 安装

    pip install selenium

  - 获取某一款浏览器的驱动程序(我用的是谷歌)

    谷歌浏览器驱动下载地址:http://chromedriver.storage.googleapis.com/index.html

    注意:下载的驱动程序必须和浏览器版本统一,大家可以根据 http://blog.csdn.net/huilan_same/article/details/51896672 中提供的版本映射表进行对应

 2 . 编码流程 

  - 导包 : from selenium import webdriver

  - 实例化一款浏览器对象

  - 自制定自动化操作代码

  注意 : 在导包的时候或许会遇到这样的问题

      

    解决 : 原因是因为 --> 开着fiddler抓包软件了,将其关掉就可以了

 3 . 简单代码示例

from selenium import webdriver
from time import sleep
# 参数地址就是 chromedriver.exe的所在目录(驱动路径)
bro = webdriver.Chrome(executable_path=r'D:\@Lily\myproject\pachong\chromedriver.exe')
bro.get(url='https://www.baidu.com/')
sleep(2) text_input = bro.find_element_by_id('kw') # 获取到输入框
text_input.send_keys('人民币')
sleep(2) search_btn = bro.find_element_by_id('su').click() # 获取到搜索按钮,并点击
sleep(2) # 获取当前的页面源码数据
page_text = bro.page_source
print(page_text) bro.quit() # 关闭浏览器

 4 . 示例 : 获取豆瓣电影更多详情数据 

from selenium import webdriver
from time import sleep url = 'https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90&action='
bro = webdriver.Chrome(executable_path=r'D:\@Lily\myproject\pachong\chromedriver.exe') bro.get(url=url)
sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 浏览器向下滚动一屏的距离
sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 浏览器向下滚动一屏的距离
sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 浏览器向下滚动一屏的距离
sleep(2) page_text = bro.page_source
with open('./douban.html','w',encoding='utf8') as f:
f.write(page_text) bro.quit()

 5 . 示例 : 模拟登陆爬取QQ空间示例(嵌套iframe框架)

#qq空间
bro = webdriver.Chrome(executable_path=r'D:\@Lily\myproject\pachong\chromedriver.exe')
url = 'https://qzone.qq.com/'
bro.get(url=url)
sleep(2)
#定位到一个具体的iframe
bro.switch_to.frame('login_frame')
bro.find_element_by_id('switcher_plogin').click()
sleep(2) bro.find_element_by_id('u').send_keys('QQ空间用户名')
bro.find_element_by_id('p').send_keys('QQ空间密码') bro.find_element_by_id('login_button').click() sleep(5) page_text = bro.page_source
with open('qq.html','w',encoding='utf-8') as fp:
fp.write(page_text)
bro.quit()

 6 . PhantomJs(无界面浏览器)

  PhantomJS是一款无界面的浏览器,其自动化操作流程和上述操作谷歌浏览器是一致的。由于是无界面的,为了能够展示自动化操作流程,PhantomJS为用户提供了一个截屏的功能,使用save_screenshot函数实现。

# 以获取豆瓣电影为例,仅仅在实例化浏览器对象时有区别,其他并无区别
from selenium import webdriver
from time import sleep url = 'https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90&action='
bro = webdriver.Chrome(executable_path=r'D:\@Lily\myproject\pachong\phantomjs.exe') bro.get(url=url)
sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 浏览器向下滚动一屏的距离 sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 浏览器向下滚动一屏的距离
sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 浏览器向下滚动一屏的距离
sleep(2) page_text = bro.page_source
with open('./douban.html','w',encoding='utf8') as f:
f.write(page_text) bro.quit()

 7 . 谷歌无头浏览器

  由于PhantomJs最近已经停止更新和维护了,所以还是推荐使用谷歌无头浏览器,是一款无界面的谷歌浏览器.

#谷歌无头浏览器
from selenium.webdriver.chrome.options import Options # 创建一个参数对象,用来控制chrome以无界面方式打开
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu') #获取豆瓣电影中更多电影详情数据
url = 'https://movie.douban.com/typerank?type_name=%E6%83%8A%E6%82%9A&type=19&interval_id=100:90&action='
bro = webdriver.Chrome(executable_path=r'D:\@Lily\myproject\pachong\chromedriver.exe',chrome_options=chrome_options)
bro.get(url)
sleep(3)
bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
sleep(3)
bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
sleep(3)
bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
sleep(2)
page_text = bro.page_source with open('./douban.html','w',encoding='utf-8') as fp:
fp.write(page_text)
print(page_text)
sleep(1)
bro.quit()

三 . 线程池

   现在使用的是基于 multiprocessing.dummy线程池

1 . 示例 : 爬取梨视频热门视频

# 爬取梨视频数据
import requests
import re
from lxml import etree
#导入线程池模块
from multiprocessing.dummy import Pool
import random # 实例化一个线程池对象
pool = Pool(5)
url = 'https://www.pearvideo.com/category_1'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
}
# 获取首页页面数据
page_text = requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
li_list = tree.xpath('//div[@id="listvideoList"]/ul/li') video_url_list = []
for li in li_list:
detail_url = 'https://www.pearvideo.com/'+li.xpath('./div/a/@href')[0]
detail_page = requests.get(url=detail_url,headers=headers).text
video_url = re.findall('srcUrl="(.*?)",vdoUrl',detail_page,re.S)[0]
video_url_list.append(video_url) video_data_list = pool.map(getVideoData, video_url_list)
pool.map(saveVideo, video_data_list) def getVideoData(url):
return requests.get(url=url,headers=headers).content def saveVideo(data):
fileName = str(random.randint(0,5000))+'.mp4'
with open(fileName,'wb') as fp:
fp.write(data)

四 . 总结

  本篇涉及到的反爬机制

    - 验证码

    - 动态加载

模拟登陆,selenium,线程池的更多相关文章

  1. 爬虫之 cookie , 验证码,模拟登陆,线程

    需求文档的定制 糗事百科的段子内容和作者(xpath的管道符)名称进行爬取,然后存储到mysql中or文本 http://sc.chinaz.com/jianli/free.html爬取简历模板 HT ...

  2. Java并发编程之线程池及示例

    1.Executor 线程池顶级接口.定义方法,void execute(Runnable).方法是用于处理任务的一个服务方法.调用者提供Runnable 接口的实现,线程池通过线程执行这个 Runn ...

  3. Python脚本模拟登陆DVWA

    目录 requests模拟登陆 Selenium自动化测试登陆 环境:python3.7 windows requests模拟登陆 我们登陆DVWA的时候,看似只有一步:访问网站,输入用户名和密码,登 ...

  4. 爬虫 requests模块的其他用法 抽屉网线程池回调爬取+保存实例,gihub登陆实例

    requests模块的其他用法 #通常我们在发送请求时都需要带上请求头,请求头是将自身伪装成浏览器的关键,常见的有用的请求头如下 Host Referer #大型网站通常都会根据该参数判断请求的来源 ...

  5. 使用线程池模拟处理耗时任务,通过websocket提高用户体验

    前言 在文章开始之前,询问一下大家平时工作中后端处理批量任务(耗时任务)的时候,前端是如何告知用户任务的执行情况的? 楼主对这个问题想了下,决定使用websokect将这一过程展现给用户. 于是就有了 ...

  6. 使用ThreadGroup模拟线程池

    参考文章: [1]创建线程池 http://sunnylocus.iteye.com/blog/223327?page=2#comments [2]线程组ThreadGroup  http://hub ...

  7. 自定义ThreadPoolExecutor带Queue缓冲队列的线程池 + JMeter模拟并发下单请求

    .原文:https://blog.csdn.net/u011677147/article/details/80271174 拓展: https://github.com/jwpttcg66/GameT ...

  8. 模拟登陆百度以及Selenium 的基本用法

    模拟登陆百度,需要依赖于selenium 模块,调用浏览器,执行python命令 先来说一下这个selenium模块啦...... 本文参考内容来自 Selenium官网 SeleniumPython ...

  9. Selenium模拟登陆百度贴吧

    Selenium模拟登陆百度贴吧 from selenium import webdriver from time import sleep from selenium.webdriver.commo ...

随机推荐

  1. 查找python项目依赖并生成requirements.txt

    1.如果使用virtualenv环境,直接使用 pip freeze > requirements.txt ➜  ~ .virtualenvs/xxx/bin/pip freeze > r ...

  2. SQL 语句基础

    一 查询常量1. SELECT 学生编号, 学生姓名,性别 FROM tb_Student2. SELECT 学生姓名 AS 姓名, 性别 AS 学生性别 FROM tb_Student3. SELE ...

  3. Kali Linux信息收集工具全

    可能大部分渗透测试者都想成为网络空间的007,而我个人的目标却是成为Q先生! 看过007系列电影的朋友,应该都还记得那个戏份不多但一直都在的Q先生(由于年级太长目前已经退休).他为007发明了众多神奇 ...

  4. linux使用tar命令打包压缩时排除某个文件夹或文件

    今天在使用tar命令进行文件夹打包压缩的时候,需要打包压缩masalaPage目录,但是该目录中的2017,2016两个目录中的文件不进行打包压缩 所以通常使用的tar -zcvf masalaPag ...

  5. 【秀优越(xie e)】原来出题也能够这么恶心。

    通过邪恶的数据范围和数据限制居然能够把一道传统题出成题答2333. 诶毕竟内部互測,题目就不往上贴了. 特殊限制 - - - 题目作废.输出M行"Orz  PoPoQQQ" - M ...

  6. c# using三种用法

    http://www.cnblogs.com/fashui/archive/2011/09/29/2195061.html http://www.cnblogs.com/iamv/archive/20 ...

  7. 面试题:使用finalkeyword修饰一个变量时,是引用不能变,还是引用的对象不能变?

    /* * 问题:使用finalkeyword修饰一个变量时,是引用不能变,还是引用的对象不能变 * 答: * 使用finalkeyword修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内 ...

  8. qrCode生成二维码图片

    QRCode.js 是一个用于生成二维码图片的插件. 1.文件脚本 var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,th ...

  9. windows下rsync部署安装

    windows下rsync部署安装 2012-06-05 12:06:13|  分类: 系统 |  标签:rsync  windows   |字号 订阅   rsync在windows与windows ...

  10. Chrome自带恐龙小游戏的源码研究(七)

    在上一篇<Chrome自带恐龙小游戏的源码研究(六)>中研究了恐龙的跳跃过程,这一篇研究恐龙与障碍物之间的碰撞检测. 碰撞盒子 游戏中采用的是矩形(非旋转矩形)碰撞.这类碰撞优点是计算比较 ...